QRegularExpression使用
模板
QString text = "s232323 f232323 s2313123";
QRegularExpression re("\\w\\d+");
//1.单一匹配
QRegularExpressionMatch match = re.match(text);
qDebug() << match.captured(0);
//2.全局匹配
QRegularExpressionMatchIterator iterator = re.globalMatch(text);
while (iterator.hasNext()) {QRegularExpressionMatch match = iterator.next();qDebug() << "Match found:" << match.captured(0);
}
匹配模式
-
基础匹配
QRegularExpression re("abc"); // 匹配”abc“
-
字符类
模式 说明 示例 [abc]匹配 a/b/c 任一字符 re("[aeiou]")[^abc]匹配非 a/b/c 的字符 re("[^0-9]")[a-z]字母范围 re("[A-Za-z]")\d数字 ≡ [0-9] re("\\d+")\w单词字符 ≡ [A-Za-z0-9_] re("\\w+@")\s空白字符(空格/制表符等) re("name\\s*:") -
量词(控制匹配次数)
模式 说明 示例 *0次或多次 re("a*b")→ "b", "aab"+1次或多次 re("a+b")→ "ab", "aab"?0次或1次 re("colou?r"){n}精确n次 re("\\d{4}"){n,}至少n次 re("\\d{3,}"){n,m}n到m次 re("\\d{2,4}")QRegularExpression re("<.*?>"); // 匹配最短的 <...>
-
分组与捕获
// 匹配日期并捕获年月日
QRegularExpression dateRe("(\\d{4})-(\\d{2})-(\\d{2})");
QRegularExpressionMatch match = dateRe.match("2023-05-15");
if (match.hasMatch()) {qDebug() << "Year:" << match.captured(1); // 2023qDebug() << "Month:" << match.captured(2); // 05
}QRegularExpression re("(?<year>\\d{4})-(?<month>\\d{2})");
match = re.match("2023-05");
qDebug() << match.captured("year"); // 2023
-
边界匹配
模式 说明 示例 ^行/字符串开始 re("^Start")$行/字符串结束 re("end$")\b单词边界 re("\\bword\\b")\B非单词边界 re("\\Bword\\B") -
模式修饰符
通过
QRegularExpression::PatternOption设置:// 忽略大小写 | 多行模式 re.setPatternOptions(QRegularExpression::CaseInsensitiveOption | QRegularExpression::MultilineOption);选项 说明 CaseInsensitiveOption忽略大小写 DotMatchesEverythingOption.匹配包括换行符MultilineOption^/$匹配每行首尾ExtendedPatternSyntaxOption支持扩展语法(注释等)
实例
-
邮箱验证
QRegularExpression emailRe(R"(\b[A-Z0-9._%+-]+@[A-Z0-9.-]+\.[A-Z]{2,}\b)" ,QRegularExpression::CaseInsensitiveOption);\b用于表示单词边界,确保匹配电子邮件地址是一个独立的单次[A-Z0-9.-%+-]+匹配待女子邮件地址部分,(+)表示可以出现多次@匹配@符号,电子邮件的分隔符[A-Z0-9.__]+匹配电子邮件的域名位置.匹配‘.’字符,需要\转义[A-Z]{2,}匹配顶级域名,如com、org等QRegularExpression::CaseInsensitiveOption:指定正则表达式匹配时不区分大小写。
-
url提取
QRegularExpression urlRe(R"(https?|ftp).//[^\s/$.?#].[^\s]*");https?这里的?紧靠s所以,s匹配0或1次也就是s可有可无,匹配可能是http/httpshttps?|ftp匹配http/https 或者ftp.//匹配地址中的.//部分[^\s/$.?#][^]表示不匹配其中的字符,这里表示不匹配空格,/,.,?,#字符。[^\s]*不以空格结尾。*匹配0或者多次,+匹配1或多次。
-
html标签内容提取
QRegularExpression tagRe("<title>(.*?)</title>");<title>匹配<title>(.\*?).匹配任意字符,*匹配0或任意次,? 使匹配模式变为非贪婪模式,即尽可能少地匹配字符。这确保了匹配范围从<title>到第一个</title>,而不是最后一个</title>。</title>匹配字符串</title>
-
数字格式化
QString str = "1234567"; str.replace(QRegularExpression("(\\d)(?=(\\d{3})+$)"), "\\1,"); // 结果: "1,234,567"\\d匹配一个数字(?=(\\d{3})+$)这是一个正向肯定断言(Positive Lookahead),表示在当前位置的后面查找匹配条件,但不消耗字符(即不移动匹配的“游标”)。\\d{3}:匹配三个连续的数字。(\\d{3})+:匹配一个或多个连续的三个数字的组合。$:表示字符串的结尾。
- 因此,
(?=(\\d{3})+$)表示在当前数字后面查找是否有一个或多个连续的三个数字的组合,直到字符串结尾。
-
匹配
select id,name,img from tables where字段QRegularExpression sqlRe(R"(select (.*?) from)");QRegularExpression sqlRe(R"(select [a-z,-_]+ from)");QRegularExpression sqlRe(R"(select\s+([A-Za-z,_+\s`\[\]]+)\s+from)") -
匹配多个同类型的字句
QRegularExpression sqlRe(R"(\\w\\d+\\b)"); QString text = "d232323 w23232 c232323"; QRegularExpressMatchIterator iterator = sqlRe.globalMatch(text); while(iterator.hasNext()){QRegularExpressionMathch match = iterator.next();qDebug() << match.captured(0); }QRegularExpression::globalMatch:- 这个方法返回一个
QRegularExpressionMatchIterator,它是一个迭代器,可以遍历所有匹配项。 - 通过调用
iterator.hasNext()检查是否还有下一个匹配项。 - 通过调用
iterator.next()获取下一个匹配项。
- 这个方法返回一个
QRegularExpressionMatch:- 每次调用
iterator.next()会返回一个QRegularExpressionMatch对象,表示当前的匹配结果。 - 使用
match.captured(0)获取完整的匹配字符串。
- 每次调用
零宽断言
四种零宽断言类型
| 类型 | 语法 | 作用 | 示例 |
|---|---|---|---|
| 正向肯定预查 | (?=exp) |
匹配后面紧跟 exp 的位置 |
\w+(?=@) 匹配 @ 前的单词 |
| 正向否定预查 | (?!exp) |
匹配后面不跟 exp 的位置 |
\d{3}(?!\d) 匹配后面不是数字的3位数 |
| 反向肯定预查 | (?<=exp) |
匹配前面是 exp 的位置 |
(?<=\$)\d+ 匹配 $ 后的数字 |
| 反向否定预查 | (?<!exp) |
匹配前面不是 exp 的位置 |
(?<!-)\d+ 匹配前面没有 - 的数字 |
-
正向肯定预查
QString str = "1232sasdusad"; QRegularExpression re(R"(\w{3}(?=u))"); qDebug() << re.match(str).captured(0); // 输出asd -
正向否定预查
QString str = "1232sasdusad"; QRegularExpression re(R"(\w{3}(?!\d))"); qDebug() << re.match(str).captured(0); // 输出232 -
反向肯定预查
QString str = "pppps1232sasdusad"; QRegularExpression re(R"((?<=s)\d{3})"); qDebug() << re.match(str).captured(0); // 输出123 -
反向否定预查
QString str = "pppps1232sasdusad"; QRegularExpression re(R"((?<!s)\d{3})"); qDebug() << re.match(str).captured(0); // 输出232
与QString结合
- 捕获组重组
QString date = "2023-05-15";
date.replace(QRegularExpression(R"((\d{4})-(\d{2})-(\d{2}))"), "\\2/\\3/\\1"); // 输出: "05/15/2023"
这里将每个()的内容算一个捕获组,从前之后一次编号为1,2...,在这里分别捕获(\d{4}),(\d{2}),(\d{2}),相应的编号为1,2,3.然后替换为”\\2\\3\\1“,即将编号对应的内容05,15,2023重排为"02/15/2023".
-
字符串分割
QString csv = "a,b,c,d"; QStringList parts = csv.split(QRegularExpression("\\s*,\\s*")); // 结果: ["a", "b", "c", "d"] -
多行模式处理
QString log = "Error: 404\nFile: main.cpp\nLine: 42"; QRegularExpression re("^File: (.*)$", QRegularExpression::MultilineOption); QRegularExpressionMatch match = re.match(log); qDebug() << match.captured(1); // 输出: "main.cpp"QString log = "Error: 404\nFile: main.cpp\nLine: 42"; QStringList strList = log.split(QRegularExpression("\\n"));for(const auto &p:strList){qDebug() << p; }//"Error: 404" //"File: main.cpp" //"Line: 42"