首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >正则表达式,再也不用依赖Qt了

正则表达式,再也不用依赖Qt了

作者头像
程序员的园
发布2025-07-16 16:46:00
发布2025-07-16 16:46:00
14100
代码可运行
举报
运行总次数:0
代码可运行

您好,我是昊天,C++程序员,多年的音视频开发经验,熟悉Qt、FFmpeg、OpenGL。如果你对这些感兴趣,欢迎关注我的公众号 由于AI IDE的普及,愈发感觉基础的重要性,后续我会用一系列的文章,讲解C++的基础知识点,本文是第一篇。

1. 正则表达式

正则表达式(Regular Expression,简称 Regex)是一种用于描述字符串匹配规则的工具。常用来查找、提取、验证、替换字符串中符合特定模式的内容,例如:

应用场景

举例说明

数据校验

检查手机号、邮箱、身份证号等格式是否正确

文本提取

从 HTML 中提取所有链接、从日志中提取 IP

批量替换

批量替换文件中的注释、变量名或标签

搜索分析

检索特定字段、关键词或格式,如日期、时间等

清洗数据

去除多余空格、非法字符、HTML 标签等

之前使用Qt框架的正则表达式,但是书写底层库时,不想依赖Qt框架,毕竟Qt太重了。

好在 C++ 标准库引入了正则表达式,C++ 原生支持了。

2. C++ 的正则表达式

C++11 开始,标准库 <regex> 正式引入正则表达式支持。该模块功能强大,覆盖了正则的构造、匹配、搜索、提取、替换等全流程操作。核心模块如下:

类/函数

作用

std::regex

构造正则表达式对象

std::regex_match

匹配整个字符串

std::regex_search

匹配字符串中的部分

std::regex_replace

替换匹配内容

std::smatch / std::cmatch

用于保存匹配结果(分别用于 std::string 和 C 风格字符串)

std::sregex_iterator / std::cregex_iterator

用于遍历字符串中所有匹配正则表达式的部分

std::sregex_token_iterator / std::cregex_token_iterator

用于遍历字符串中所有不匹配正则表达式的部分

为了清晰明确的展示C++中的正则表达式的用法,下面分别展示5种常见的用法。

2.1 匹配整个字符串

std::regex_match 函数用于检查整个字符串是否与正则表达式匹配。如果匹配成功,则返回 true,否则返回 false

代码语言:javascript
代码运行次数:0
运行
复制
#include <iostream>
#include <regex>

int main() {
    std::string input = "2025-07-15";
    std::regex date_pattern(R"(\d{4}-\d{2}-\d{2})");

    if (std::regex_match(input, date_pattern)) {
        std::cout << "合法日期格式" << std::endl;
    } else {
        std::cout << "非法格式" << std::endl;
    }
}

2.2 匹配字符串中的部分

std::regex_search 函数用于在字符串中搜索第一个与正则表达式匹配的部分。如果找到匹配项,则返回 true,否则返回 false

代码语言:javascript
代码运行次数:0
运行
复制
#include <iostream>
#include <regex>

int main() {
    std::string text = "我的邮箱是 user@example.com,请联系我。";
    std::regex email_pattern(R"(\b\w+@\w+\.\w+\b)");
    std::smatch match;

    if (std::regex_search(text, match, email_pattern)) {
        std::cout << "发现邮箱:" << match[0] << std::endl;
    }
}

2.3 替换匹配内容

std::regex_replace 函数用于将字符串中所有匹配正则表达式的部分替换为指定的字符串。

代码语言:javascript
代码运行次数:0
运行
复制
#include <iostream>
#include <regex>

int main() {
    std::string text = "访问我们的网站:http://example.com";
    std::regex url_pattern(R"(http://\S+)");
    std::string replaced = std::regex_replace(text, url_pattern, "[链接已屏蔽]");

    std::cout << replaced << std::endl;
}

2.4 提取多个匹配项

std::sregex_iterator 类用于遍历字符串中所有匹配正则表达式的部分,返回一个迭代器,可以像普通迭代器一样使用。

代码语言:javascript
代码运行次数:0
运行
复制
#include <iostream>
#include <regex>

int main() {
    std::string text = "联系人: tom@example.com, jerry@mail.com";
    std::regex email_pattern(R"(\b\w+@\w+\.\w+\b)");

    auto begin = std::sregex_iterator(text.begin(), text.end(), email_pattern);
    auto end = std::sregex_iterator();

    for (auto it = begin; it != end; ++it) {
        std::cout << "发现邮箱:" << it->str() << std::endl;
    }
}

2.5 提取匹配组

std::smatch 类用于保存匹配结果,支持通过索引或名称访问匹配组。

代码语言:javascript
代码运行次数:0
运行
复制
#include <iostream>
#include <regex>

int main() {
    std::string input = "电话:+86-13800138000";
    std::regex phone_pattern(R"(\+(\d+)-(\d+))");  // 分组:国家码 和 手机号
    std::smatch result;

    if (std::regex_search(input, result, phone_pattern)) {
        std::cout << "国家码: " << result[1] << ", 手机号: " << result[2] << std::endl;
    }
}

3. 注意事项

注意点

建议说明

性能问题

对长文本或复杂表达式应避免频繁创建 std::regex,应复用同一个对象

转义字符

尽量使用原始字符串字面量:R"(pattern)" 避免 \\ 混乱

匹配失败行为

regex_match 要求整个字符串匹配,regex_search 只要匹配一部分就行

某些平台兼容性差

GCC 4.8 及更早版本对 <regex> 支持不完善,推荐使用 GCC 4.9+、MSVC 2013+

正则语法不完全一致

C++11 正则库基于 ECMAScript 标准语法,但不完全等同 JS 正则的功能,例如不支持命名组、非贪婪量词略有区别。

Unicode 字符处理较弱

对中文字符建议结合 wstring 或使用外部库(如 ICU)处理更稳妥

4. 正则语法

正则语法并不是本文的重点,但是为了便于理解,同时为了文章的完整度,接下来将简单介绍正则语法ECMA标准。

4.1 基本语法

符号

作用

.

匹配除换行符以外的任意字符

^

匹配字符串的开头

$

匹配字符串的结尾

*

匹配前面的子表达式零次或多次

4.2 字符类

符号

作用

[abc]

匹配字符 a、b 或 c

[^abc]

匹配除 a、b、c 之外的任意字符

4.3 预定义字符类

符号

作用

\d

匹配数字字符(等价于 [0-9])

\D

匹配非数字字符(等价于 [^0-9])

4.4 量词

符号

作用

+

匹配前面的子表达式一次或多次

?

匹配前面的子表达式零次或一次

{n}

匹配前面的子表达式恰好 n 次

4.5 分组和反向引用

符号

作用

(pattern)

匹配并捕获 pattern

\1、\2

分别表示第一个和第二个捕获组

4.6 断言

符号

作用

(?=pattern)

正向先行断言,匹配后面是 pattern 的位置

(?!pattern)

负向先行断言,匹配后面不是 pattern 的位置

(?<=pattern)

正向后行断言,匹配前面是 pattern 的位置

(?<!pattern)

负向后行断言,匹配前面不是 pattern 的位置

5. 总结

  • 正则表达式是处理字符串的利器,在校验、提取、替换等方面无可替代。
  • C++11 引入了原生支持 <regex>,提供了完整的正则工具链。
  • 在性能和跨平台兼容性方面需注意一些细节问题。
  • 学会正则表达式,将极大提高你处理文本数据的效率。
本文参与 腾讯云自媒体同步曝光计划,分享自微信公众号。
原始发表:2025-07-15,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 程序员的园 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 1. 正则表达式
  • 2. C++ 的正则表达式
    • 2.1 匹配整个字符串
    • 2.2 匹配字符串中的部分
    • 2.3 替换匹配内容
    • 2.4 提取多个匹配项
    • 2.5 提取匹配组
  • 3. 注意事项
  • 4. 正则语法
    • 4.1 基本语法
    • 4.2 字符类
    • 4.3 预定义字符类
    • 4.4 量词
    • 4.5 分组和反向引用
    • 4.6 断言
  • 5. 总结
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档