Qt中使用正则表达式来提取字符串

在 C++ Qt 项目中,你可以使用 QRegularExpression 类结合正则表达式来匹配 QString 中的内容。下面介绍如何使用正则表达式进行匹配、提取和替换操作。

一、基本用法:创建正则表达式对象

cpp 复制代码
#include <QRegularExpression>

QString m_buffer = "Hello, 2025! Today is 2025-05-30.";

// 创建正则表达式对象(匹配四位数字)
QRegularExpression re("\\d{4}");

二、常见匹配操作

1. 检查是否匹配
cpp 复制代码
// 检查整个字符串是否匹配
bool isExactMatch = re.match(m_buffer).hasMatch();

// 检查字符串中是否包含匹配项
bool containsMatch = m_buffer.contains(re);
2. 查找第一个匹配项
cpp 复制代码
QRegularExpressionMatch match = re.match(m_buffer);
if (match.hasMatch()) {
    QString matchedText = match.captured(0); // 整个匹配的文本
    int pos = match.capturedStart(0);        // 匹配的起始位置
    int length = match.capturedLength(0);    // 匹配的长度
}
3. 查找所有匹配项
cpp 复制代码
QRegularExpressionMatchIterator it = re.globalMatch(m_buffer);
while (it.hasNext()) {
    QRegularExpressionMatch match = it.next();
    QString matchedText = match.captured(0);
    // 处理每个匹配项
}
4. 使用捕获组提取子字符串
cpp 复制代码
// 匹配日期格式:YYYY-MM-DD
QRegularExpression dateRe("(\\d{4})-(\\d{2})-(\\d{2})");
QRegularExpressionMatch match = dateRe.match(m_buffer);

if (match.hasMatch()) {
    QString fullDate = match.captured(0); // 完整匹配:2025-05-30
    QString year = match.captured(1);     // 第一组:2025
    QString month = match.captured(2);    // 第二组:05
    QString day = match.captured(3);      // 第三组:30
}

三、高级用法

1. 设置匹配选项
cpp 复制代码
// 不区分大小写
QRegularExpression re("hello", QRegularExpression::CaseInsensitiveOption);

// 多行模式(^ 和 $ 匹配行的开始和结束)
QRegularExpression multiLineRe("^\\d+", QRegularExpression::MultilineOption);
2. 替换匹配内容
cpp 复制代码
// 将所有数字替换为 "X"
QString result = m_buffer.replace(re, "X");
// 结果:"Hello, X! Today is X-X-X."

// 使用捕获组替换
QString replaced = m_buffer.replace(dateRe, "\\1年\\2月\\3日");
// 结果:"Hello, 2025! Today is 2025年05月30日."
3. 分割字符串
cpp 复制代码
// 按逗号或空格分割字符串
QRegularExpression splitRe("[,\\s]+");
QStringList parts = m_buffer.split(splitRe);

四、在你的项目中应用正则表达式

假设你需要从 dbus-monitor 的输出中提取 time= 后面的时间戳:

cpp 复制代码
QString m_buffer = "method call time=1748411906.768461 sender=:1.100 ...";

// 正则表达式:匹配 "time=" 后跟数字和小数点
QRegularExpression timeRe("time=(\\d+\\.\\d+)");
QRegularExpressionMatch match = timeRe.match(m_buffer);

if (match.hasMatch()) {
    QString timestampStr = match.captured(1); // 提取时间戳:1748411906.768461
    double timestamp = timestampStr.toDouble();
}

五、正则表达式语法参考

符号 含义 示例
^ 匹配字符串开始 ^hello
$ 匹配字符串结束 world$
. 匹配任意字符(除换行符) h.t
* 匹配前一个字符 0 次或多次 he*llo
+ 匹配前一个字符 1 次或多次 he+llo
? 匹配前一个字符 0 次或 1 次 colou?r
{n} 匹配前一个字符 n 次 a{3}
{n,} 匹配前一个字符至少 n 次 a{3,}
{n,m} 匹配前一个字符 n 到 m 次 a{3,5}
[ ] 匹配方括号中的任意字符 [aeiou]
[^ ] 匹配不在方括号中的任意字符 [^aeiou]
( ) 分组,用于捕获子字符串 (\\d{2})-(\\d{2})
` ` 或操作
\d 匹配数字(等价于 [0-9] \d{3}
\D 匹配非数字(等价于 [^0-9] \D+
\s 匹配空白字符 \s+
\S 匹配非空白字符 \S+
\w 匹配单词字符(字母、数字、下划线) \w+
\W 匹配非单词字符 \W+

六、性能注意事项

  1. 预编译正则表达式:对于频繁使用的正则表达式,建议创建为类成员变量,避免重复编译。
  2. 使用简单模式:复杂的正则表达式会显著影响性能,尽量简化。
  3. 检查匹配位置 :使用 match.capturedStart() 确定匹配位置,避免重复查找。
相关推荐
用户805533698034 天前
不止三件套:QObject 属性系统全关键字与运行时反射!
c++·qt
xcyxiner4 天前
DicomViewer (vcpkg Windows和ubuntu编译)7
qt
Quz9 天前
QML Hello World 入门示例
qt
xcyxiner12 天前
DicomViewer (dcmtk读取dcm文件)5
qt
xcyxiner12 天前
DicomViewer (后台线程处理文件)4
qt
xcyxiner13 天前
DicomViewer (添加模型类)3
qt
xcyxiner13 天前
DicomViewer (目录调整) 2
qt
xcyxiner13 天前
dcmtk vtk vtk-dicom(gdcm) 编译(debug) v2
qt
桥田智能15 天前
桥田智能 QT-650S:面向白车身焊装的 800kg 重载快换解决方案
开发语言·qt·系统架构
森G15 天前
75、服务器源码解析---------云视频服务项目
linux·服务器·网络·c++·qt