不二如是 发表于 2016-10-29 10:38:30

131-#重磅-正则表达式(Regexps)-【深度扫盲】

本帖最后由 不二如是 于 2016-10-30 17:07 编辑



没错,这次不二又要攻下一个难啃的山头儿了-正则表达式!

本来,不想讲了,因为太麻烦。。。

但不二的良知和对知识的渴望督促自己,要写出来{:10_288:}

推荐小甲鱼老湿Python系列里面的正则表达式,异曲同工,不二对经典不用多加赘言。



你没猜错,点我会传送你过去哈~ヽ(●′ε`●)ノ

来最后一起感受QRegExp波涛汹涌

然后去下一页征服她吧{:9_240:}








深深地想了想。。。

不要问不二为什么老爱用‘深’‘浅’这样的措辞,可能比较销魂吧~

哈哈,不扯远,从这四个方面,攻陷!

其中有三个山头有传送门,你们自己猜吧{:10_336:} ~


[*]简介

Regexps是由表达式(expressions)、量词(quantifiers)、断言(assertions)三位一体!


[*]表达式

最简单的一个表达式:

a


啊?{:10_287:}

没错,这就是正则表达式Regexps。



也是,甚至可以简写为:



这样就会匹配A到H之间的所有大写字母~很简单粗暴有效是不是。

很赞同小甲鱼老湿那句名言之一:

得正则表达式者得天下!!!


[*]量词

一个量词指定了必须要匹配的表达式出现的次数。

例如:
x{1,1}
x{1,9}

前者意味着有且只能匹配一个字符x

后者意味着至少包含一个x字符,但最多只能有9个。

现在假设你需要匹配0-99之间的整数。

因为至少要有一个数字,所以可以使用正则表达式(后文,均简称为reg)。

reg:
{1,1}

他匹配一个单一的数字一次!

而0-99会出现两位数字的整数,也就是整数的所有算数位上,会出现两次。

reg:
{1,2}

虽然从数字上看没问题了。

但是,可能会匹配出现在字符串中间的整数,就默认匹配到。

例如匹配45,可能匹配到4~

为了避免这个问题就要引入‘断言’

[*]断言

断言就是解决上面那个问题而发明的。

‘^’、'$' 就是断言!

'^'在reg中作为第一个字符时,意味着reg必须从字符串的开始进行匹配。

'$'在reg中作为最后一个字符时,意味着reg必须匹配到字符串的结尾。

而最后用reg匹配0-99之间的整数表达式就是:

^{1,2}$

[*]特殊符号的情趣用法

不仅是Qt,任何用到正则表达式的地方,都会用到特殊符号来服务自己{:10_278:} 。

例如,就可以使用'\d'来代替哈~

对于量词x{1,1}就可以使用'x'本身来代替~

那么匹配0-99之间的整数就可以简化为:

^\d{1,2}$Or^\d\d{0,1}$

{0,1}量词的意思是可选的,至多出现1次,就可以使用'?'来代替。

这样进一步简化就是:

^\d\d? $

当然了,别看这么简单,但是表达的意思还是:

从字符串开始,匹配一个数字,紧接着是0或1个数字,在接着是0或1个数字,最后是字符串的结尾!

记住,永远不要忘记为什么开始!



[*]组成元素

[*]表达式中字符和字符集缩写



元素 含义
c 一个字符代表它本身,除非这个字符有特殊的reg含义
如,a匹配字符a
\c 跟在反斜杠后面的字符匹配字符本身
但是本表下面的字符除外!
例如要匹配一个字符串的开头,使用\^
\a 匹配ASCII的振铃(BEL,0x07)
\f 匹配ASCII的换页(FF,0x0C)
\n 匹配ASCII的换行(LF,0x0A)
\r 匹配ASCII的回车(CR,0x0D)
\t 匹配ASCII的水平制表符(HT,0x09)
\v 匹配ASCII的垂直制表符(VT,0x0B)
\xhhh 匹配Unicode字符对应的十六进制hhhh(0x0000~0xFFFF之间)
\0ooo 匹配八进制的ASCII\Latin1字符ooo(0~0377之间)
. 匹配任意字符(包括新行)
\d 匹配一个数字
\D 匹配一个非数字
\s 匹配一个空白字符,'\t'、'\n'、'\v'、'\f'、'\r'、' '
\S 匹配一个非空白字符
\w 匹配一个单词字符,包括任意一个字母、数字、下划线
即A~Z、a~z、0~9、_四个中任意一个
\W 匹配一个非单词字符
\n 第n个反向引用,例如,\1\2



[*]量词



量词 含义
E? 匹配0次或者1次,表明E是可选的,E?等价于E{0,1}
E+ 匹配1次或者多次,E+等价于E{1,}
例如,0+匹配‘0’、‘00’、‘000’等
E* 匹配0次或者多次,等价于E{0,}
E{n] 匹配n次,等价于E{n,n}
例如x{5}等价于x{5,5},即xxxxx
E{n,} 匹配至少n次
E{,m} 匹配至多m次,等价于E{0,m}
E{n,m} 匹配至少n次,至多m次


注意:

量词非常贪婪(Greedy)

例如,0+匹配他发现的第一个0以及其随后所有的连续0!

匹配到“300008”字符时,他会匹配其中4个连续的0!

要想使其非贪婪(non-greedy),可以使用setMinimal(true),这样只会匹配第一个0哈~


[*]断言



断言 含义
^ 标志着字符串的开始。
如果要匹配^就要使用\\^
$ 标志着字符串的结尾。
如果要匹配¥就要使用\\$
\b 一个单词的边界
\B 一个非单词的边界,当\b为false时他为true
(? = E) 表达式后面紧跟着E才匹配。
例如,const(? =\s+char)匹配‘const’且其后必须有‘char’才行
(?! E) 表达式后面没有紧跟着E才匹配。
例如,const(?! \s+char)匹配“const”但其后不能有‘char’



[*]通配符



字符 含义
c 任意一个字符,表示字符本身
? 匹配任意一个字符,类似于reg中的‘.’
* 匹配0个或者多个任意的字符,类似于reg中‘.*’
[...]在方括号中的字符集,与reg中的类似


例如你要匹配本地的所有'.txt'类型文件,那么就要这么搞:
QRegExp re("*.txt");
rx.setPatternStntax(QRexExp::Wildcard);


[*]语法


常量 描述
QRegExp::RegExp 类似于Perl的模式匹配语法,这个是默认语法
QRegExp::RegExp2 类似于RegExp,不过是一种贪婪匹配算法
QRegExp::Wildcard 一种简单的模式匹配语法
QRegExp::WildcardUnix 与Wildcard类似,但是使用Unix shell的行为
QRegExp::FixedString 使用字符愿意,不使用任何的字符转意
QRegExp::W3CXmlSchemall 在W3C XML Schema 1.1规范中定义的一种正则表达式




[*]应用

正则表达式英文全称(Regular Expression)

就是在一个文本中匹配子字符串的一种模式(pattern),可以简写"regexp"

常用在一下几个方面:

[*]验证

一个reg可以测试一个子字符串是否符合一些‘需要’的标准。

例如,是一个整数或者不包含任何空格等


[*]搜索

一个reg提供了比简单的子字符串匹配更强大的模式匹配。

例如,匹配单词mail或者letter,而不匹配单次email或者letterbox。


[*]查找和替换

一个reg可以使用一个不同的字符串替换一个字符串中所有要替换的子字符串。

例如,使用Mail替换一个字符串中所有的M字符,但是如果M字符后面有ail就不要替换了。


[*]字符串分割

一个reg可以识别在哪里进行字符串分割。

例如,分割制表符的字符串



[*]文本抓取

在reg中使用括号可以使一些元素组合在一起,既可以进行量化、也可以进行捕获他们。

例如,使用mail|letter来匹配一个字符串,则知道有一个会被匹配,但却不知道具体是哪一个

进而,使用(mail|letter)来匹配"I like ur emali",这样就可以使用cap()或者capturedTexts()函数匹配字符。后面有例子憋急~

还可以在reg中使用捕获到的文本,使用反向引号'\n',表示捕获到的文本。

其中,n从1开始编号,比如,\1就表示第一个捕获到的文本。

例如,在一个字符串中查询出现的单词:

\b(\w+)\W+\1\b

意味着先匹配一个单词边界->一个或者多个单词字符->一个或者多个非单词字符->与前面的第一个括号中相同的文本->单词边界

使用括号仅仅是为了组合元素!

而不是为了捕获文本,这点一定要清楚~

使用非捕获语法
(?:red|blue)

由(?:开始)结束。

非捕获括号比使用捕获括号更高效,因为reg引擎只需做较少内存工作~


不二如是 发表于 2016-10-29 16:22:13

@小甲鱼 请小甲鱼老湿看看是否写的很粗暴有效?

~风介~ 发表于 2016-10-29 20:54:38

终于认识到自己是视觉性动物的事实!{:10_250:}

不二如是 发表于 2016-10-29 21:09:56

~风介~ 发表于 2016-10-29 20:54
终于认识到自己是视觉性动物的事实!

{:10_257:}有男人的地方就有女人,这是江湖
大家都着色{:10_279:}

zzzz76 发表于 2016-10-30 12:11:09

不去下一页了,我们一定不合适,全是英文呢,{:10_250:}

不二如是 发表于 2016-10-30 12:24:03

zzzz76 发表于 2016-10-30 12:11
不去下一页了,我们一定不合适,全是英文呢,

哈哈,后面都是都给你翻译成中文了

zzzz76 发表于 2016-10-30 12:47:49

翻译的好棒!!
qt好玩吗,找个时间咱也来探探此坑{:10_310:}

不二如是 发表于 2016-10-30 15:22:22

zzzz76 发表于 2016-10-30 12:47
翻译的好棒!!
qt好玩吗,找个时间咱也来探探此坑

哈哈,可好玩儿了

比MFC好玩儿~
随时欢迎

小甲鱼 发表于 2016-11-11 15:48:10

话说你为啥要分两页~~~

不二如是 发表于 2016-11-11 16:26:01

小甲鱼 发表于 2016-11-11 15:48
话说你为啥要分两页~~~

就像鲁迅说的:

我家门前有两棵树

一棵是枣树、另一颗也是枣树
页: [1]
查看完整版本: 131-#重磅-正则表达式(Regexps)-【深度扫盲】