正则表达式调试工具实战
正则表达式介绍
正则表达式(Regular Expressions,简称 regex 或 regexp)是一种用于描述字符串模式的工具,它可以用来查找、匹配、替换和验证文本。正则表达式广泛应用于各种编程语言和文本处理工具中,如 Python、Java、JavaScript、C#、Perl 等。
1. 基本概念
模式:正则表达式定义的字符串模式,可以用于匹配特定的文本。
字符类:用于定义一组字符,可以用方括号 [ ] 表示。
元字符:具有特殊意义的字符,如 .、*、+、? 等。
2. 正则表达式的语法
2.1 字符匹配
.:匹配除换行符以外的任何单个字符。
示例:a.b 可以匹配 acb、axb 等。
^:匹配字符串的开头。
示例:^abc 匹配以 abc 开头的字符串。
$:匹配字符串的结尾。
示例:xyz$ 匹配以 xyz 结尾的字符串。
2.2 字符类
[abc]:匹配括号内的任意一个字符。
示例:[aeiou] 匹配任意一个元音字母。
[^abc]:匹配不在括号内的字符。
示例:[^0-9] 匹配任意非数字字符。
[a-z]:匹配指定范围内的字符(小写字母)。
示例:[A-Z] 匹配任意大写字母。
2.3 量词
*:匹配前一个元素零次或多次。
示例:a* 可以匹配 “”、“a”、“aa”。
+:匹配前一个元素一次或多次。
示例:a+ 可以匹配 “a”、“aa”,但不匹配 “”。
?:匹配前一个元素零次或一次。
示例:a? 可以匹配 “” 或 “a”。
{n}:匹配前一个元素恰好 n 次。
示例:a{3} 只匹配 “aaa”。
{n,}:匹配前一个元素至少 n 次。
示例:a{2,} 匹配 “aa”、“aaa” 等。
{n,m}:匹配前一个元素至少 n 次,但不超过 m 次。
示例:a{1,3} 匹配 “a”、“aa”、“aaa”。
2.4 分组与选择
( ):用于分组和提取子匹配。
示例:(abc)+ 匹配 “abc”、“abcabc” 等。
|:表示逻辑“或”操作。
示例:abc|def 匹配 “abc” 或 “def”。
2.5 特殊字符
\:转义字符,用于匹配元字符的字面意义。
示例:. 匹配字符 .。
\d:匹配任何数字,等同于 [0-9]。
\D:匹配任何非数字字符,等同于 [^0-9]。
\w:匹配任何字母数字字符(包括下划线),等同于 [a-zA-Z0-9_]。
\W:匹配任何非字母数字字符,等同于 [^a-zA-Z0-9_]。
\s:匹配任何空白字符(空格、制表符等)。
\S:匹配任何非空白字符。
3. 正则表达式的应用
3.1 验证输入
正则表达式常用于验证用户输入,例如电子邮件地址、电话号码等。
1+@([\w-]+.)+[\w-]{2,4}$
上述表达式用于验证常见的电子邮件格式。
3.2 查找和替换
可以用正则表达式进行文本查找和替换。
import re
text = "Hello, World!"
查找并替换
new_text = re.sub(r’World’, ‘Regex’, text)
print(new_text) # 输出: Hello, Regex!
3.3 解析日志文件
可以使用正则表达式从日志文件中提取特定信息,如日期、IP 地址等。
(\d{4}-\d{2}-\d{2})\s+(\d+\.\d+\.\d+\.\d+)
上述表达式用于匹配日期和 IP 地址。
4. 性能注意事项
贪婪与懒惰匹配:默认情况下,量词是贪婪的,即尽可能多地匹配字符。如果需要最少匹配,可以在量词后加上 ?,如 *?、+?、??。
避免过度复杂的模式:复杂的正则表达式可能导致性能下降,特别是在处理大文本时。
1、新建工程QWidget工程工程名RegexTool
如果QT不会配置,请参考我的博客,QT配置
Widget.cpp 默认内容如下
2、主界面设计
- 三行两列,每行采用HBoxLayout作为行布局控件,内部一个Lable控件和一个TextEdit控件,采用VBoxLayout 控件包裹三个HBoxLayout控件,最后把VBoxLayout加入主页面即可完成设计
实现代码如下
//主界面的高度
this->setFixedHeight(500);
//设置主界面宽度
this->setFixedWidth(800);
//设置主界面的Title内容
this->setWindowTitle("正则表达式测试工具");
//构造垂直布局控件
QVBoxLayout *vlayout = new QVBoxLayout();
QLabel *label1,*label2,*label3;
QHBoxLayout *l1,*l2,*l3;
label1 = new QLabel();
label2 = new QLabel();
label3 = new QLabel();
lineEdit1 = new QTextEdit();
lineEdit2 = new QTextEdit();
lineEdit3 = new QTextEdit();
//==========================================第一行布局========================================//
l1 = new QHBoxLayout();
//设置文本对齐方式
label1->setAlignment(Qt::AlignmentFlag::AlignTop);
//设置文本宽度
label1->setFixedWidth(120);
//设置文本的内容
label1->setText("正则表达式 : ");
//设置正则表达式输入框的高度
lineEdit1->setFixedHeight(60);
//设置输入框的对齐方式
lineEdit1->setAlignment(Qt::AlignmentFlag::AlignLeft | Qt::AlignmentFlag::AlignTop);
//这里设置了一些样式
SetLineEditStyle(lineEdit1);
//设置水平容器内容对齐方式
l1->setAlignment(Qt::AlignmentFlag::AlignTop);
//控件加入容器
l1->addWidget(label1);
l1->addWidget(lineEdit1);
//水平容器加入垂直容器
vlayout->addLayout(l1);
//==========================================第二行布局========================================//
lineEdit2->setFixedHeight(200);
lineEdit2->setAlignment(Qt::AlignmentFlag::AlignLeft | Qt::AlignmentFlag::AlignTop);
SetLineEditStyle(lineEdit2);
label2->setAlignment(Qt::AlignmentFlag::AlignTop);
l2 = new QHBoxLayout();
label2->setFixedWidth(120);
l2->setAlignment(Qt::AlignmentFlag::AlignTop);
label2->setText("匹配字符串 : ");
l2->addWidget(label2);
l2->addWidget(lineEdit2);
vlayout->addLayout(l2);
//==========================================第三行布局=======================================//
lineEdit3->setReadOnly(true);
lineEdit3->setFixedHeight(200);
QTextCursor cursor = lineEdit3->textCursor(); // 获取 QTextEdit 的光标
QTextBlockFormat blockFormat;
blockFormat.setLineHeight(300, QTextBlockFormat::ProportionalHeight); // 设置 3 倍行高
cursor.setBlockFormat(blockFormat);
lineEdit3->setAlignment(Qt::AlignmentFlag::AlignLeft | Qt::AlignmentFlag::AlignTop);
SetLineEditStyle(lineEdit3);
label3->setAlignment(Qt::AlignmentFlag::AlignTop);
l3 = new QHBoxLayout();
l3->setAlignment(Qt::AlignmentFlag::AlignTop|Qt::AlignmentFlag::AlignRight);
label3->setText(" 匹配结果 : ");
label3->setFixedWidth(120);
l3->addWidget(label3);
l3->addWidget(lineEdit3);
vlayout->addLayout(l3);
//==========================================加入主页面=======================================//
this->setLayout(vlayout);
3、逻辑实现
1、绑定TextChange事件
//绑定第一个输入框的Textchange事件,绑定到StartMatch槽函数上
connect(lineEdit1,&QTextEdit::textChanged,this,&Widget::StartMatch);
//绑定第二个输入框的Textchange事件,绑定到StartMatch槽函数上
connect(lineEdit2,&QTextEdit::textChanged,this,&Widget::StartMatch);
2、实现代码逻辑
//正则表达式内容
QString regexStr = lineEdit1->toPlainText();
//匹配字符串内容
QString matchStr = lineEdit2->toPlainText();
if(regexStr.isEmpty() || matchStr.isEmpty()) {
lineEdit3->setText("没有匹配到任何数据!");
return;
}
//正则表达式逻辑实现
QRegularExpression regex;
regex.setPattern(regexStr);
QRegularExpressionMatch match = regex.match(matchStr);
if (!match.hasMatch()) {
lineEdit3->setText("没有匹配到任何数据!");
return;
}
//获取内容
QList<QString> result = match.capturedTexts();
if(result.isEmpty()){
lineEdit3->setText("没有匹配到任何数据!");
return;
}
QString res;
res.append("匹配到");
res.append(QString::number(result.count()));
res.append("个结果\r\n");
for (int i = 0; i < result.count(); ++i) {
res.append("结果" + QString::number(i+1) +" : " + result[i]+"\r\n");
}
//内容输出到第三个文本框
lineEdit3->setText(res);
4、工具下载
https://download.csdn.net/download/weixin_42462436/89823286
\w-. ↩︎