Qt 正则表达式(QRegularExpression类)详解
Qt 正则表达式(QRegularExpression类)详解
一、正则表达式介绍
正则表达式(Regular Expression,简称 Regex)是一种用于描述文本模式的强大工具。它通过特定的语法规则,定义字符串的匹配模式,常用于文本的搜索、匹配、替换和验证操作。正则表达式在文本处理、数据清洗、表单验证等场景中应用广泛。
1、核心语法规则
以下是正则表达式的常用语法元素:
| 符号 | 含义 |
|---|---|
. | 匹配任意单个字符(除换行符) |
* | 匹配前一个字符零次或多次 |
+ | 匹配前一个字符一次或多次 |
? | 匹配前一个字符零次或一次 |
\d | 匹配数字(等价于 [0-9]) |
\w | 匹配字母、数字或下划线(等价于 [a-zA-Z0-9_]) |
\s | 匹配空白字符(空格、制表符等) |
[abc] | 匹配方括号内的任意一个字符(如 a、b 或 c) |
[^abc] | 匹配不在方括号内的任意字符 |
(abc) | 分组,将多个字符视为一个单元 |
^ | 匹配字符串开头 |
$ | 匹配字符串结尾 |
| | 逻辑或(如 a|b 匹配 a 或 b) |
2、实用示例
假设需要验证一个电话号码格式(如 138-1234-5678),可用以下正则表达式:
^\d{3}-\d{4}-\d{4}$ ^和$确保匹配整个字符串\d{3}匹配3位数字-匹配连字符
3、常用场景
- 数据提取
从日志中提取IP地址:\b\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}\b
表单验证
邮箱格式校验:
^\w+([.-]?\w+)*@\w+([.-]?\w+)*(\.\w{2,3})+$ 文本替换
将日期格式 2023/08/15 替换为 2023-08-15:
(\d{4})/(\d{2})/(\d{2}) 替换为:$1-$2-$3
4、常用正则表达式
| 用途描述 | 正则表达式 | 示例匹配值 |
|---|---|---|
| 电子邮箱地址 | ^\w+([\.-]?\w+)*@\w+([\.-]?\w+)*(\.\w{2,3})+$ | [email protected] |
| 中国大陆手机号 | ^1[3-9]\d{9}$ | 13800138000 |
| 日期格式 (YYYY-MM-DD) | ^\d{4}-\d{2}-\d{2}$ | 2023-08-15 |
| 中文汉字 | ^[\u4e00-\u9fa5]+$ | 你好世界 |
| 身份证号 (15/18位) | ^(\d{15}|\d{17}[\dXx])$ | 11010519900101123X |
| IP地址 | ^\d{1,3}(\.\d{1,3}){3}$ | 192.168.0.1 |
| 强密码 (8-20位含大小写字母、数字、特殊字符) | ^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[\W_]).{8,20}$ | Passw0rd! |
| 整数(含负数) | ^-?\d+$ | -42, 100 |
| 特殊字符检测 | [<>"';&\\] | <script> |
💡 提示:实际使用时建议根据具体场景调整表达式边界(如添加 ^...$ 严格匹配),并使用在线测试工具验证匹配效果。
5、工具推荐
- 在线测试:RegExr
- 代码支持:Python 的
re模块、JavaScript 的RegExp对象
二、 QRegularExpression类详解
QRegularExpression 是 Qt6 中用于处理正则表达式的核心类。它提供了强大且高效的字符串模式匹配功能,遵循 Perl 兼容的正则表达式语法(PCRE)。在 Qt6 中,它替代了旧的 QRegExp 类,并提供了更好的性能、功能完整性和 Unicode 支持。
1、核心功能
- 模式匹配: 检查字符串是否匹配给定的模式。
- 捕获匹配: 提取与正则表达式中定义的子模式(捕获组)匹配的子字符串。
- 全局匹配: 查找字符串中所有出现的匹配项。
- 字符串操作: 支持查找、替换、分割等基于正则表达式的操作(通常结合
QString的相关方法)。
2、基本使用步骤
"subject string"是要匹配的目标字符串。offset(可选) 指定开始匹配的起始位置。matchType(可选) 指定匹配选项(如部分匹配、锚定匹配等)。
获取捕获组:
正则表达式中的圆括号 () 定义捕获组。
// 假设模式为 "^(\\d+)-(\\d+)$" (匹配 "123-456")int group1 = match.captured(1).toInt();// 获取第一个捕获组 "123"int group2 = match.captured(2).toInt();// 获取第二个捕获组 "456" QString entireMatch = match.captured(0);// 获取整个匹配 "123-456"检查匹配结果:
if(match.hasMatch()){// 成功匹配 QString matched = match.captured(0);// 获取整个匹配的字符串// ... 处理匹配结果}else{// 未匹配if(match.hasPartialMatch()){// 存在部分匹配(如果启用了相关选项)}}进行匹配:
QRegularExpressionMatch match = re.match("subject string");或者
QRegularExpressionMatch match = re.match("subject string", offset, matchType);创建正则表达式对象:
QRegularExpression re("pattern");其中 "pattern" 是您的正则表达式字符串。
3、常用方法
bool isValid() const: 检查正则表达式模式语法是否有效。QString errorString() const: 如果无效,获取错误信息。QString pattern() const: 获取当前设置的正则表达式模式。void setPattern(const QString &pattern): 设置新的正则表达式模式。void setPatternOptions(QRegularExpression::PatternOptions options): 设置匹配选项(如忽略大小写CaseInsensitiveOption、多行模式MultilineOption等)。int captureCount() const: 获取捕获组的数量(不包括第 0 组)。QRegularExpressionMatchIterator globalMatch(const QString &subject) const: 获取一个迭代器,用于遍历字符串中所有匹配项。
4、全局匹配示例
查找字符串中所有出现的单词:
QString text ="The quick brown fox jumps over the lazy dog."; QRegularExpression re("\\b\\w+\\b");// 匹配单词边界之间的字符 QRegularExpressionMatchIterator i = re.globalMatch(text);while(i.hasNext()){ QRegularExpressionMatch match = i.next();qDebug()<< match.captured(0);// 输出: "The", "quick", "brown", ...}5、模式选项
可以通过 setPatternOptions 或使用内联标记设置选项:
// 忽略大小写 QRegularExpression re("hello", QRegularExpression::CaseInsensitiveOption); re.match("Hello");// 匹配成功// 内联标记 (?i) QRegularExpression re("(?i)hello"); re.match("Hello");// 匹配成功常用选项:
NoPatternOption: 无选项(默认)。CaseInsensitiveOption: 忽略大小写。DotMatchesEverythingOption:.匹配包括换行符在内的任何字符。MultilineOption:^和$匹配每行的开始和结束,而非整个字符串。ExtendedPatternSyntaxOption: 忽略未转义空格和#后的注释。InvertedGreedinessOption: 反转*和+的贪婪性(使其不贪婪)。DontCaptureOption: 非命名捕获组不捕获(仅命名捕获组有效)。UseUnicodePropertiesOption: 使\w,\d等字符类遵循 Unicode 属性。
6、常见用例示例
6.1、验证电子邮件地址 (简化版)
QRegularExpression emailRe("^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}$"); QString email ="[email protected]";if(emailRe.match(email).hasMatch()){qDebug()<<"Valid email";}else{qDebug()<<"Invalid email";}6.2、提取 URL 协议和域名
QString url ="https://www.example.com/path"; QRegularExpression urlRe("^(https?)://([^/]+)"); QRegularExpressionMatch match = urlRe.match(url);if(match.hasMatch()){ QString protocol = match.captured(1);// "http" 或 "https" QString domain = match.captured(2);// "www.example.com"}6.3、替换所有数字
QString text ="Order 123, Item 456"; QRegularExpression digitRe("\\d+"); QString result = text.replace(digitRe,"NUM");// 结果: "Order NUM, Item NUM"7、注意事项
- 语法: 确保熟悉 Perl 兼容正则表达式语法。
- 转义: 在 C++ 字符串中,反斜杠
\需要转义为\\(例如,\d应写作"\\d")。 - 性能: 对于非常复杂的模式或极长的字符串,注意性能影响。考虑优化正则表达式或使用其他字符串处理方法。
- 错误处理: 始终检查
isValid()并在无效时查看errorString()。 - Qt 版本:
QRegularExpression是 Qt5.1 引入的,在 Qt6 中是主要的正则表达式处理类。
三、代码示例
1、效果展示

2、源码分享
#include"mainwindow.h"#include"ui_mainwindow.h"#include<QCoreApplication>#include<QJsonDocument>#include<QJsonObject>#include<QJsonArray>#include<QJsonValue>#include<QDebug>#include<QFile>#include<QRegularExpression>MainWindow::MainWindow(QWidget *parent):QMainWindow(parent),ui(new Ui::MainWindow){ ui->setupUi(this);}MainWindow::~MainWindow(){delete ui;}voidMainWindow::on_pushButton_clicked(){// 示例1:基础匹配 QString text ="Qt 6.2 released on 2021-09-30"; QRegularExpression datePattern(R"(\d{4}-\d{2}-\d{2})"); QRegularExpressionMatch match = datePattern.match(text);if(match.hasMatch()){qDebug()<<"找到日期:"<< match.captured(0);// 输出: "2021-09-30"}// 示例1:全局匹配(查找所有) QString html ="<p>Hello <b>World</b>!</p>"; QRegularExpression tagPattern(R"(<(\w+)>(.*?)</\1>)"); QRegularExpressionMatchIterator it = tagPattern.globalMatch(html);while(it.hasNext()){ QRegularExpressionMatch tagMatch = it.next();qDebug()<<"标签:"<< tagMatch.captured(1)<<"内容:"<< tagMatch.captured(2);// 输出:// 标签: "b" 内容: "World"// 标签: "p" 内容: "Hello <b>World</b>!"}// 示例3:替换操作 QString phone ="Tel: (123) 456-7890"; QRegularExpression phonePattern(R"(\((\d{3})\)\s(\d{3})-(\d{4}))"); QString formatted = phone.replace(phonePattern,R"(\1-\2-\3)");qDebug()<<"格式化电话:"<< formatted;// 输出: "Tel: 123-456-7890"}