关于正则表达式的介绍,先看我这个博客:
qt中正则表达式类是 QRegularExpression;
QRegularExpression 支持标准正则表达式(其实标准也有多种,perl(目前使用最广泛的标准,qt也最接近这个),JavaScript,python,posix);
但是标准正则表达式还有不足的地方,QRegularExpression就提供了一些选项 来补充这些不足,而且能让正则表达式的写法更简单一点;
所以创建时可以指定该对象选项(但是和正则表达式里已写的控制符不冲突 ,正则表达式里写的优先生效 的,可以放心)(下面多个参数可以用**|或运算组合使用**):
- MultilineOption 就能让 ^和$匹配的是串里每一行的开头和结尾,而不是整个串的开头和结尾
- DotMatchesEverythingOption 就能让.号匹配里面的换行符了(默认标准一般是不匹配的,即.相当于 \^\\r\\n)
- CaseInsensitiveOption 能不区分大小写的进行匹配(就不需要a-zA-Z这种写法了,只需要a-z就行,更简洁了)
- ExtendedPatternSyntaxOption(默认开启) 允许扩展语法,例如允许空格,#号加表达式注释
- InvertedGreedinessOption 反转量词贪婪性,不常用
- DontCaptureOption 括号(...)仅分组,而不实际捕获内容,如果标准正则语法就得写为 (?:...),当然如果正则表达式里已经写了(?:...),那么就会忽略设置的该参数了
- UseUnicodePropertiesOption 使得能理解Unicode编码字符串的匹配(常见的都叫做ascii串),例如\w匹配Unicode下的单词(例如中文单词),而不是ascii下的单词
注意 MultilineOption 、DotMatchesEverythingOption 这两个常常被组合起来使用来创建对象就行。
然后就执行QRegularExpression中的match和globalMatch,核心区别在于返回值和覆盖范围:
- match()只匹配到第一个目标串就结束了
- globalMatch()会从输入串的头匹配查找到结尾,找出所有匹配项,所以是返回迭代器的
match函数的两个可选参数:
=》MatchType 定义匹配的"完整度:
- NormalMatch(默认):标准模式,默认行为。要求整个表达式必须完整匹配才能成功。如果匹配失败,就意味着没有符合要求的完整结果。
- PartialPreferCompleteMatch:这个模式会先尝试完整匹配。如果没有完整匹配,但部分的匹配(如 \d+ 只匹配到行首的数字) 有可能在未来新数据到来后变为完整匹配,就会报告一个部分匹配。适合自动补全或增量输入验证。 例如 \dabc 那么用户输入 1 也会返回为匹配,因为部分匹配了,这样方便提示用户输入的前缀目前来看是对的
- PartialPreferFirstMatch:这个模式会优先返回匹配到的最短子串。如果没有完整匹配,也会返回部分匹配。适合匹配语法高亮这类场景。
- NoMatch:一个内部标记,表明上一次匹配已经结束,不用于手动调用
=》MatchOptions定义匹配的"规则:(可以用|或运算来组合使用)
- AnchoredMatchOption:强制匹配必须从 offset 指定的位置开始,即使在正则表达式中没有使用 ^ 这样的锚定符号。
- AnchorAtOffsetMatchOption:与 AnchoredMatchOption 不同,它只对用户手动传入的 offset 起点生效。
- DontCheckSubjectStringMatchOption:这是一个性能优化选项。当你知道待匹配的文本(subject string)不会在使用期间被修改时,启用它可以避免某些内部的状态检查,从而提升性能。
- NoMatchOption(默认):不应用任何特殊匹配规则
普通搜索:使用默认的 (NormalMatch, NoMatchOption) 即可。
其它知识:
在 Qt/C++ 中,原始字符串字面量使用 R"(...)" 的形式 ,其中 ... 部分直到遇到第一个 )" 才会结束。
如果字符串内容里恰好包含了 )" 这个子串,则会提前结束,例如 R"(^"(\^"*)"|^(\S+))" 就会报错了
应该使用自定义分隔符来避免内容中的 )" 被误识别。语法为 R"delim( ...)delim ",其中 delim 是你自己选择的任意字符序列(只要不出现在字符串内容中即可,而且可以多字符 )