QRegularExpression
QRegularExpression主要由pattern string和pattern options集合组成,构造一个对象,可以使用
1 | QRegularExpression re("a pattern"); |
或
1 | QRegularExpression re; |
如果想在pattern string中包含’',则需要使用转义”\“,如
1 | // matches two digits followed by a space and a word |
Pattern Options
在构造函数中设置
1 | // 设置匹配大小写 |
通过setPatternOptions设置
1 | QRegularExpression re("^\\d+$"); |
通过patternOptions获取当前设置
1 | QRegularExpression re = QRegularExpression("^two.*words$", QRegularExpression::MultilineOption | QRegularExpression::DotMatchesEverythingOption); |
Match Type and Match Options
match和globalMatch函数的最后两个参数是match type和match options,match type指定了匹配算法,默认是NormalMatch。
Normal Matching
要执行一次match,只需要调用match函数,并传递要匹配的字符串即可,返回值是一个QRegularExpressionMatch对象。
1 | // match two digits followed by a space and a word |
如果match成功,通过QRegularExpressionMatch对象可以获取到匹配元素:
1 | QRegularExpression re("\\d\\d \\w+"); |
可以传递一个偏移值,相对于搜索串的偏移,如下,”12 abc”不会被搜索到,因为是从搜索串的偏移1开始搜索:
1 | QRegularExpression re("\\d\\d \\w+"); |
Extracting captured substrings
captured(int nth = 0)函数能够返回匹配组的第nth个对象:
1 | QRegularExpression re("^(\\d\\d)/(\\d\\d)/(\\d\\d\\d\\d)$"); |
匹配组的索引是从开始的,索引为0表示完全匹配pattern的字符串。
capturedStart(int nth = 0)和capturedEnd(int nth = 0)可以返回匹配字符串在搜索串中的位置,匹配串的长度即为 和capturedEnd - capturedStart:
1 | QRegularExpression re("abc(\\d+)def"); |
可以给每个匹配项命名:
1 | QRegularExpression re("^(?<date>\\d\\d)/(?<month>\\d\\d)/(?<year>\\d\\d\\d\\d)$"); |
Global Matching// 搜索全部
如下例子匹配所有单词,其中,返回值i指向的是第一个匹配项前的位置:
1 | QRegularExpression re("(\\w+)"); |
globalMatch函数的返回值是一个QRegularExpressionMatchIterator对象,通过它能够获取匹配结果,hasNext为true表示还有不止一个结果,next返回下一个结果集:
1 | QStringList words; |
Partial Matching// 部分匹配
部分匹配是指搜索串已到了结尾,但还需要更多字符串去达到完全匹配的结果。
当部分匹配找到的时候,hasMatch返回false且hasPartialMatch返回true。同时可以通过captured(0)获取到部分匹配的字符串。
注意:当指定部分匹配的时候,也会同时进行完全匹配。如果有完全匹配,则hasMatch返回true而hasPartialMatch返回false。但不会存在两者同时为true的情况。
1 | re.setPattern("(\\dabc\\d)"); |
Validating user input
假设我们要验证用户输入的日期是否符合某个格式,可以使用这样的匹配模式:
1 | ^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \d\d?, \d\d\d\d$ |
以下使用的都是PartialPreferCompleteMatch模式。
只有部分匹配的情况:
1 | QString pattern("^(Jan|Feb|Mar|Apr|May|Jun|Jul|Aug|Sep|Oct|Nov|Dec) \\d\\d?, \\d\\d\\d\\d$"); |
有全部匹配的情况:
1 | QString input("Dec 8, 1985"); |
另一种匹配模式的表现:
有全部匹配的情况:
1 | QRegularExpression re("abc\\w+X|def"); |
abc\w+X部分匹配,而def全部匹配。
如果有多个部分匹配(但没有全部匹配),则第一个找到的将会返回:
1 | QRegularExpression re("abc\\w+X|defY"); |
Incremental/multi-segment matching
1 | QRegularExpression re("abc|ab"); |
当第一个abc匹配模式查找到的时候即返回,此时为部分匹配。
还有两个更加特殊的例子:
1 | QRegularExpression re("abc(def)?"); |
以上例子是因为?和*都是greedy的(贪心),它们会尽可能匹配一个或多个,所以当找到abc的时候,它们会接着查找,但此时已到达搜索串结尾,所以返回的是部分匹配。
Error Handling
可以通过QRegularExpression的isValid和errorString函数获取错误信息:
1 | QRegularExpression invalidRe("(unmatched|parenthesis"); |
如果QRegularExpression无效,则match函数返回的QRegularExpressionMatch对象也无效。
Unsupported Perl-compatible Regular Expressions Features
Qt未完全支持Perl的正则表达式语法,可能会在未来版本中添加。
Notes for QRegExp Users
与QRegExp的差异,略。
推荐新版本都使用QRegularExpression。
QRegExp
Qt中的正则表达式。
正则表达式由表达式、数量词和断言组成。
表达式,如单个字符’x’或’5’或某个字符集合,如[A-Z]。
数量词,指定了某个表达式出现的次数,如x{1,1}表示刚刚好出现一次x,x{1,5}则表示x最少出现一次,最多出现5次。
注意,正则表达式最好不要用来搜索配对括号或标签。因为配对的是,但在bold bolder中,第一个应该是跟第二个配对。
在正则表达式中,^和$分别表示搜索字符串的开始和结尾。如搜索串应只包含匹配项,不包含其他字符。
假设我们要匹配0~99,要匹配刚好一个数字的话,是[0-9]{1,1},那如果要匹配两个数字的话,则是[0-9]{1,2},如果像表示匹配串是整个搜索串的话,则可以写成^ [0-9]{1,2}$。
实现同样的功能,正则表达式可以有不同的写法。比如[0-9],也可以写为\d。数量词可以使用表达式本身表示,如x{1,1},可以写为x。要匹配0~99的话,也可以写成^ \d{1,2}$,同样可以写为^\d\d?$,因为?是数量词{1,2}的缩写,表示出现0或1次。?表示一个表达式时可选的。
如果我们想要匹配 ‘mail’ or ‘letter’ or ‘correspondence’,但不匹配包含它们的单词。我们可以使用’mail|letter|correspondence’,但这个同样会匹配到’email’, ‘mailman’, ‘mailer’, and ‘letterbox’。为了避免这种情况,我们需要指定搜索词的边界,指定单词的边界,可以使用\b标签,如\b(mail|letter|correspondence)\b。\b表示的是单词的位置,单词的边界是任何非词字符,如空格,换行,或者字符串的开头或结尾。
如果我们想要将’&’替换为html entity ‘&’,如果简单使用正则表达式’&’,则会匹配到原本已经转换过的&,这不是我们想要的。此时,可以使用负向后行断言,’(?!__)’,所以可以写成’&(?!amp;)’,就能够匹配到那些不是不是&中的&。
Characters and Abbreviations for Sets of Characters
Element | Meaning |
---|---|
c | 字符c |
\c | 字符c |
\a | ASCII bell (BEL, 0x07) |
\f | ASCII form feed (FF, 0x0C) |
\n | ASCII line feed (LF, 0x0A, Unix newline). |
\r | ASCII carriage return (CR, 0x0D). |
\t | ASCII horizontal tab (HT, 0x09). |
\v | ASCII vertical tab (VT, 0x0B). |
\xhhhh | Unicode character corresponding to the hexadecimal number hhhh (between 0x0000 and 0xFFFF). |
\0ooo (i.e., \zero ooo) | ASCII/Latin1 character for the octal number ooo (between 0 and 0377). |
. (dot) | 任意字符,包括换行符 |
\d | 数字 |
\D | 非数字 |
\s | 空格字符 |
\S | 非空格字符 |
\w | word字符,包括字母、数字、下划线 |
\W | 非word字符 |
\s | 空格字符 |
\S | 非空格字符 |
Sets of Characters
[]中括号表示一个集合,包含在里面的表达式都会进行匹配。但有两种特殊情况:
中括号内的^表示不包括,比如[abc]表示匹配a或b或c,但[^abc]就表示包含除了a和b和c以外的所有字符。
中括号的-表示一个连续的序列,比如[W-Z]表示W或X或Y或Z。
Quantifiers
E代表表达式,表达式可以是一个字符,或一个字符集的缩略表示,或者中括号表示的字符集,或者用括号包含的表达式。
表达式 | 备注 |
---|---|
E? | E出现0次或1次,E是可选的。跟E{0,1}是一样的,如,dents?能匹配到’dent’或’dents’. |
E+ | E出现一次或多次,跟E{1,}一样,如,0+能匹配到 ‘0’, ‘00’, ‘000’等等. |
E* | E出现0次或多次,跟E{0,}是一样的. |
E{n} | E出现正好n次. |
E{n,} | E出现最少n次. |
E{,m} | E出现最多m次. |
E{n,m} | E出现最少n次,最多m次. |
注意,在使用数量词的时候,最好使用括号括起来,比如,tag+匹配包含那些ta和至少出现一个g的。而(tag)+匹配最少出现一个tag的。
Capturing Text
略。
Assertions
表达式 | 备注 |
---|---|
^ | 表示字符串的起始位置,如果想匹配’^’字符,则需要使用\^ |
$ | 表示字符串的终止位置,如果想匹配’$’字符,则需要使用\$ |
\b | word边界,注意是不包含空格的,比如将(\bOK\b)应用到’It’s OK now’中,将只会匹配’OK’ |
\B | 非word边界,与\b的作用相反。将’\Bon\B’应用到”Left on”将会失败,但应用到”tonne”则会成功 |
(?=E) | 正向先行断言,比如,将’const(?=\s+char)’应用到’static const char *’中,将会匹配’const’。区别于’const\s+char’,将匹配’const char’ |
(?!E) | 反向先行断言,比如,将’const(?=\s+char)’将匹配那些后面不接’char’的’const’ |
Wildcard Matching(通配符匹配)
表达式 | 备注 |
---|---|
c | 字符c |
? | 匹配任意单个字符,同正则表达式中的’.’作用一样 |
* | 匹配0个或多个字符,同正则表达式中的’.*’作用一样 |
[…] | 匹配任意单个字符,同正则表达式中的’.’作用一样 |
使用exactMatch函数检测字符串是否符合通配符模式:
1 | QRegExp rx("*.txt"); |