basic_regex

1. 它的真实身份:由“字符类型”决定的模板

你很少会在代码里直接写 basic_regex,因为它是一个模板(Template)。它需要根据你处理的是“普通文字”还是“宽字符(如中文等多字节字符)”来变形。

C++ 已经为你定义好了两个最常用的别名(Aliases),你应该直接使用这两个:

别名 对应的完整写法 用途
std::regex std::basic_regex<char> 最常用。用于处理标准的 std::string
std::wregex std::basic_regex<wchar_t> 用于处理宽字符 std::wstring (处理复杂中文环境时可能会用到)。

一句话总结:写代码时,请直接写 std::regex


2. 如何定义规则(构造函数)

定义一个 basic_regex 主要关注两点:字符串模式标志位(Flags)

A. 这里的“坑”:转义字符

在 C++ 中,\ 是转义符。而在正则表达式中,\ 也是转义符。

如果你想匹配一个数字 \d:

  • 错误写法"\d" (C++ 编译器会报错,或者把它当成特殊字符)。

  • 普通写法"\\d" (你要告诉 C++ “我想要一个反斜杠”,所以要写两个)。

  • 高手写法(推荐):使用 Raw String Literal R"(...)"

// 假设我们要匹配一个数字 "\d"
std::regex r1("\\d");     // 普通写法:容易眼花,斜杠满天飞
std::regex r2(R"(\d)");   // Raw String写法:括号里是什么,规则就是什么。推荐!

B. 标志位(Syntax Options)

你可以在定义规则时,通过第二个参数告诉它“怎么读这个规则”。

  • std::regex::icase忽略大小写 (Ignore Case)。比如 a 可以匹配 A

  • std::regex::optimize:告诉引擎“你先花点时间优化一下规则,因为我后面要用它匹配很多次”。

  • 默认模式:C++ 默认使用 ECMAScript 语法(和 JavaScript 的正则语法一样),这是最强大的标准。

示例:

// 规则:匹配 "abc",但是忽略大小写
std::regex myPattern("abc", std::regex::icase);
// 结果:能匹配 "ABC", "Abc", "abc"...

3. 实战代码详解

下面这段代码展示了 std::regex (即 basic_regex 的化身) 的完整生命周期:

#include <iostream>
#include <regex>
#include <string>

int main() {
    // 1. 数据源
    std::string text = "我的邮箱是 User@Example.com,请联系我。";

    // 2. 定义 basic_regex (使用 std::regex)
    // 解释规则 R"(...)":
    // [a-zA-Z]+  -> 也就是名字部分
    // @          -> 艾特符号
    // [a-zA-Z.]+ -> 域名部分
    // std::regex::icase -> 忽略大小写,所以 pattern 里不用写大写字母也能匹配
    std::regex email_pattern(R"([a-z]+@[a-z.]+)", std::regex::icase);

    // 3. 准备接收结果
    std::smatch results; // 存放 sub_match 的容器

    // 4. 执行匹配
    // regex_search 会拿着 email_pattern 这个“模具”去 text 里找
    if (std::regex_search(text, results, email_pattern)) {
        std::cout << "找到邮箱: " << results.str() << std::endl;
    } else {
        std::cout << "没找到!" << std::endl;
    }

    return 0;
}

核心 [a-z]+@[a-z.]+ (正则表达式)

去掉外壳后,剩下的就是我们要让电脑执行的规则。我们把它拆解开来:

片段 含义详解
[a-z] “字符集”:表示匹配 任意一个 小写字母(从 a 到 z)。
+ “量词”:表示前面的东西出现 1次或多次。 组合起来 [a-z]+ 意思就是:一串小写字母(比如 “user”, “abc”)。
@ “字面量”:就代表 @ 这个符号本身。
[a-z.] “字符集”:表示匹配 任意一个 小写字母 或者 一个点(.)。 注意:在方括号 [] 里面,点 . 就是普通的点,不需要转义。
+ “量词”:表示前面的东西(字母或点)出现 1次或多次。 组合起来 [a-z.]+ 意思就是:一串由字母和点组成的域名(比如 “gmail.com”, “co.jp”)。

4. 性能上的重要提示 (高手必知)

basic_regex 的构造是非常“重”的。

当电脑看到 std::regex pattern(“…”) 这行代码时,它需要把你的字符串翻译成一种内部的“状态机”。这很耗费 CPU。

  • 不要在循环里定义 regex

  • 把它定义成 static 或者放在循环外面。

错误示范(很慢):

for (int i = 0; i < 10000; ++i) {
    std::regex r(R"(\d+)"); // 每次循环都要重新编译规则,极慢!
    // ... 匹配 ...
}

正确示范(很快):

static std::regex r(R"(\d+)"); // 只编译一次,重复使用
for (int i = 0; i < 10000; ++i) {
    // ... 匹配 ...
}

总结

  1. basic_regex 是核心模板,平时请用 std::regex

  2. 写规则字符串时,尽量用 R"(...)" 来避免写一堆 \\

  3. 如果需要忽略大小写,加参数 std::regex::icase

  4. 不要在循环内部反复创建它,因为它初始化很慢。

发表评论