目录
QRegularExpression
1. QRegularExpression 概述
QRegularExpression
是 Qt 5.10 引入的类,用于处理正则表达式。它提供了更现代和高效的正则表达式功能,支持 Perl 兼容的正则表达式(PCRE),与之前的 QRegExp
相比,性能和功能都得到增强。
正则表达式(regex)是处理字符串和文本的强大工具,广泛应用于各种场景。以下是一些常见的用法:
关于正则表达式的好参考包括:
- Jeffrey E. F. Friedl著《掌握正则表达式(第三版)》,ISBN 0-596-52812-4;
- pcrepattern(3)手册页,描述了PCRE支持的模式语法(perl兼容正则表达式的参考实现);
- Perl的正则表达式文档和Perl的正则表达式教程。
2. 基本用法
2.1 创建正则表达式对象
#include <QRegularExpression>
#include <QString>
#include <QDebug>
int main()
{
QString pattern = R"(\d+)"; // 匹配一个或多个数字
QRegularExpression regex(pattern);
if (!regex.isValid())
{
qDebug() << "Invalid regular expression!";
}
return 0;
}
2.2 匹配字符串
使用 match
方法进行单次匹配:
QString text = "The number is 12345.";
QRegularExpressionMatch match = regex.match(text);
if (match.hasMatch())
{
qDebug() << "Match found:" << match.captured(0); // 捕获整个匹配
}
else
{
qDebug() << "No match found.";
}
2.3 查找所有匹配项
使用 globalMatch
查找所有匹配项:
QString text = "Numbers: 123, 456, 789.";
QRegularExpressionMatchIterator it = regex.globalMatch(text);
while (it.hasNext())
{
QRegularExpressionMatch match = it.next();
qDebug() << "Match found:" << match.captured(0);
}
2.4 使用捕获组
正则表达式可以包含捕获组,用于提取子模式:
QString pattern = R"(\d+)-(\w+)"; // 匹配数字-字母组合
QRegularExpression regex(pattern);
QString text = "Order number is 1234-ABCD.";
QRegularExpressionMatch match = regex.match(text);
if (match.hasMatch())
{
qDebug() << "Full match:" << match.captured(0); // 整个匹配
qDebug() << "First group:" << match.captured(1); // 第一个捕获组
qDebug() << "Second group:" << match.captured(2); // 第二个捕获组
}
2.5 替换字符串
使用 QString::replace
方法与正则表达式结合,可以进行替换操作:
QString pattern = R"(\d+)"; // 匹配一个或多个数字
QRegularExpression regex(pattern);
QString text = "Replace 123 with XYZ.";
QString replacedText = text.replace(regex, "XYZ");
qDebug() << "Original text:" << text;
qDebug() << "Replaced text:" << replacedText; // 输出: "Replace XYZ with XYZ."
3. 正则表达式常见操作
- 匹配:使用
match()
方法。 - 查找:使用
globalMatch()
方法获取所有匹配项。 - 替换:使用
QString::replace()
方法结合正则表达式。 - 捕获组:使用括号
()
来定义捕获组,通过captured()
方法访问。
4. 进阶功能
-
模式修饰符:可以使用模式修饰符来改变匹配行为,例如忽略大小写。
QRegularExpression regex("pattern", QRegularExpression::CaseInsensitiveOption);
-
支持 Unicode:
QRegularExpression
自然支持 Unicode 字符集。
5. 字符串匹配和替换示例
以下是一个完整的示例,展示了如何使用 QRegularExpression
进行字符串匹配和替换:
#include <QCoreApplication>
#include <QRegularExpression>
#include <QString>
#include <QDebug>
int main(int argc, char *argv[])
{
QCoreApplication a(argc, argv);
QString pattern = R"(\d+)"; // 匹配数字
QRegularExpression regex(pattern);
QString text = "Extract numbers: 42 and 1001.";
// 匹配和提取
QRegularExpressionMatchIterator it = regex.globalMatch(text);
while (it.hasNext())
{
QRegularExpressionMatch match = it.next();
qDebug() << "Match found:" << match.captured(0);
}
// 替换
QString replacedText = text.replace(regex, "NUMBER");
qDebug() << "Replaced text:" << replacedText;
return a.exec();
}
6. 性能优化
虽然 QRegularExpression
提供了强大的功能,但在处理复杂正则表达式或大文本时,性能可能成为一个问题。以下是一些优化建议:
-
编译正则表达式:如果一个正则表达式需要多次使用,可以考虑将其编译为
QRegularExpression
对象,避免重复编译。QRegularExpression regex("your_pattern");
-
限制匹配范围:尽量减少待匹配文本的范围。例如,可以先进行简单的字符串搜索,确定是否有必要执行复杂的正则表达式匹配。
7. 错误处理
QRegularExpression
提供了错误处理机制,以便在正则表达式无效时获取详细信息。可以使用 errorString()
方法获取错误信息。
QString invalidPattern = "[";
QRegularExpression regex(invalidPattern);
if (!regex.isValid())
{
qDebug() << "Error:" << regex.errorString();
}
8. 常见正则表达式模式
以下是一些常见的正则表达式模式:
-
匹配邮箱地址:
R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})"
-
匹配URL:
R"((https?://[^\s/$.?#].[^\s]*)"
-
匹配电话号码(简单示例,可能需要根据实际情况调整):
R"(\+?\d{1,3}[- ]?\(?\d{1,4}?\)?[- ]?\d{1,4}[- ]?\d{1,9})"
9. 实际应用示例
以下是一些实际应用场景,展示了如何使用 QRegularExpression
处理不同类型的文本数据。
9.1 验证输入格式
假设你需要验证用户输入的邮箱格式:
QString email = "example@domain.com";
QRegularExpression emailRegex(R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})");
if (emailRegex.match(email).hasMatch())
{
qDebug() << "Valid email format.";
}
else
{
qDebug() << "Invalid email format.";
}
9.2 从文本中提取信息
假设你需要从日志文件中提取时间戳和错误信息:
QString logData = "2023-10-01 12:34:56 ERROR Something went wrong.";
QRegularExpression logRegex(R"((\d{4}-\d{2}-\d{2} \d{2}:\d{2}:\d{2}) (ERROR|WARNING|INFO) (.+))");
QRegularExpressionMatch match = logRegex.match(logData);
if (match.hasMatch())
{
qDebug() << "Timestamp:" << match.captured(1);
qDebug() << "Log Level:" << match.captured(2);
qDebug() << "Message:" << match.captured(3);
}
9.3 替换敏感词
假设你需要过滤用户评论中的敏感词:
QString comment = "This is a bad and ugly comment.";
QString sensitiveWords = R"(bad|ugly)"; // 可以根据需求添加更多词汇
QRegularExpression regex(sensitiveWords);
QString filteredComment = comment.replace(regex, "***");
qDebug() << "Filtered comment:" << filteredComment;
10. QRegularExpression 文档概述
下面是关于 QRegularExpression
相关类和枚举的详细说明,包括其成员类型和用法介绍。
10.1 QRegularExpression::MatchOptions
MatchOptions
枚举定义了用于匹配时的选项。
10.2 QRegularExpression::MatchType
MatchType
枚举定义了匹配类型的选项。
10.3 QRegularExpression::PatternOption
PatternOption
枚举定义了正则表达式模式的选项。
10.4 QRegularExpression::WildcardConversionOption
WildcardConversionOption
枚举定义了将通配符模式转换为正则表达式模式的方式。
10.5 QRegularExpressionMatch
QRegularExpressionMatch
类表示正则表达式的匹配结果,提供了匹配信息获取的方法,如捕获的子字符串和匹配位置等。
示例代码:
QString text = "Example: 12345";
QRegularExpression regex(R"(\d+)");
QRegularExpressionMatch match = regex.match(text);
if (match.hasMatch())
{
qDebug() << "Matched value:" << match.captured(0); // 输出捕获的数字
qDebug() << "Start position:" << match.capturedStart(0);
qDebug() << "End position:" << match.capturedEnd(0);
}
10.6 QRegularExpressionMatchIterator
QRegularExpressionMatchIterator
用于迭代多个匹配结果。可以通过 globalMatch()
方法获取所有匹配。
示例代码:
QString text = "Numbers: 123, 456, 789";
QRegularExpression regex(R"(\d+)");
QRegularExpressionMatchIterator it = regex.globalMatch(text);
while (it.hasNext())
{
QRegularExpressionMatch match = it.next();
qDebug() << "Found:" << match.captured(0);
}
10.7 QRegularExpressionValidator
QRegularExpressionValidator
使用正则表达式来验证输入字符串的有效性。它可以判断输入是否接受、处于中间状态或无效。
示例代码:
#include <QRegularExpressionValidator>
#include <QString>
QString pattern = "[A-Z][0-9]"; // 示例正则表达式
QRegularExpressionValidator validator(QRegularExpression(pattern));
QString input = "A1";
int pos = 0; // 输入位置
if (validator.validate(input, pos) == QValidator::Acceptable)
{
qDebug() << "Input is valid.";
}
else
{
qDebug() << "Input is invalid.";
}