正则表达式(Regular Expression,简称 regex)本质上是用一段特定格式的字符串来定义某种文本模式,通过该模式可检验目标字符串是否符合预设特征。它是处理字符串匹配、检验、替换等操作的高效工具。简单来讲,正则表达式可被视为一种用于字符串模式验证的“规则模板”。例如,正则表达式“ab+”定义的模式为“一个字符'a'后跟随一个或多个字符'b'”,因此字符串“ab”“abb”“abbbbbbbbbb”均符合该模式要求。
在 C++ 中,正则表达式功能主要由标准库头文件 `<regex>` 提供,支持字符串的匹配、查找、替换及格式验证等核心操作。该库自 C++11 标准起首次引入,并在 C++14 与 C++17 标准中逐步完成功能扩展与完善。
接下来本文将从语法指定方式、核心构成单元(元素)、重复规则、串联与替换逻辑、语法差异摘要及关键语义细节六个维度,系统梳理 C++ 正则表达式的完整语法体系。
Part1 正则表达式语法
C++ 的 std::regex 支持多种正则表达式风格,std::regex 所用的正则表达式语法,通过 std::regex_constants::syntax_option_type 枚举值 指定,所有语法规则均定义在 std::regex_constants 命名空间中。

注意:只能指定一个语法类型。若未显式指定,则默认使用 ECMAScript。
此外,还可以结合以下标志来控制匹配行为:
- icase:忽略大小写进行匹配。
- nosubs:不保存捕获组结果。
- optimize:优化匹配速度,可能增加构造时间。
- collate:启用区域设置敏感的排序规则(如 [a-z] 在不同 locale 下含义不同)。
这些标志可以与任意语法组合使用。如果仅传递标志而没有指定语法,仍会采用 ECMAScript 作为默认语法。
Part2 元素构成
正则表达式由「元素」构成,每个元素对应目标文本中的一个匹配单元。
2.1、通用元素(所有语法均支持)
1). 一般字符
匹配规则:直接匹配目标序列中相同的字符(无特殊含义的字符)。
示例:a 可匹配 "a",但不匹配 "B"、"b" 或 "c"。
2). 通配符 .
匹配规则:匹配目标序列中除 换行符 外的任意字符。
示例:. 可匹配 "a"、"B"、"1"、"!" 等,但不匹配 "\n"。
3). 括号表达式 [expr]/ [^expr]
作用:定义一个「字符 / 排序规则元素集合」,用于匹配集合内(或外)的字符。
- [expr]:匹配集合内的字符;
- [^expr]:匹配集合外的字符(^ 表示否定)。
其中 expr 可由以下成分组合而成:
- 单个字符:直接将字符加入集合(如 [abc] 包含 a、b、c);
- 字符范围 ch1-ch2:加入闭区间 [ch1, ch2] 内的所有字符(如 [0-9] 匹配数字);
- 字符类 [:name:]:加入预定义命名类的字符(如 [:lower:] 匹配小写字母);
- 等价类 [=elt=]:加入与 elt 等价的排序规则元素(依赖 locale);
- 排序规则符号 [.elt.]:加入排序规则元素 elt(如多字符视为单个单元)。
示例:
- [b-z] 匹配 "b"、"c",但不匹配 "a"、"B";
- [^0-9] 匹配非数字字符(如 "a"、"!")。
4). 定位点 ^/ $
匹配规则:匹配目标序列中的「位置」,而非字符。
- ^:匹配目标序列的开头(如 ^a 仅匹配以 "a" 开头的文本);
- $:匹配目标序列的结尾(如 a$ 仅匹配以 "a" 结尾的文本)。
5). 捕获组 (子表达式)/ 子表达式
作用:将子表达式标记为一个「单元」,同时存储与子表达式匹配的文本(供后续引用)。
语法差异:
- basic/ grep 语法:需用 子表达式(括号需转义);
- 其他语法(如 ECMAScript、extended):直接用 (子表达式)。
示例:(a) 可匹配 "a",并将捕获组 1 与 "a" 关联,不匹配 "B"、"b"。
6). 标识转义 \k
作用:匹配字符 k,移除 k 的特殊含义(当 k 是元字符时需用)。
示例:a\* 不匹配 "aaa"(* 失去重复含义),仅匹配 "a*"。
4.2、ECMAScript 特有元素
ECMAScript 语法支持更多扩展元素,满足复杂场景需求:

示例:
- (?:a)匹配 "a",但 (?:a)\1 无效(无捕获组 1);
- a\b.匹配 "a~",不匹配 "ab"(\b 匹配字边界);
- (?=a)a 匹配 "a"(肯定断言匹配 a,后续 a 再次匹配同一位置)。
4.3、awk 特有元素
awk 语法在 extended 基础上增加了以下元素:
- 文件格式转义:支持 \\(反斜杠)、\a(警报符)、\b(退格符)等,补充了 ECMAScript 不支持的 \a 和 \b;
- 八进制转义:\ooo(1-3 个八进制数),匹配对应八进制值的字符(如 \101 匹配 "A")。
Part3 元素的重复规则
除「肯定断言、否定断言、定位点」外,所有元素均可后接「重复计数」,定义元素的匹配次数。

示例:
- a{2,3}匹配 "aa"、"aaa",不匹配 "a"、"aaaa";
- a* 匹配 ""(空字符串)、"a"、"aa" 等。
3.2、扩展重复格式(除 basic/grep 外)
ECMAScript、extended、egrep、awk 还支持以下简化重复格式:
- ?:等价于 {0,1},匹配 0 次或 1 次(如 a? 匹配 ""、"a");
- +:等价于 {1, 无限},匹配 1 次或多次(如 a+ 匹配 "a"、"aa")。
3.3、非贪婪重复(ECMAScript 特有)
默认重复为「贪婪模式」(匹配最长可能的序列),在重复计数后加 ? 可切换为「非贪婪模式」(匹配最短可能的序列)。
示例:
- 贪婪模式:(a+)(a*b) 匹配 "aaab" 时,a+ 匹配 "aaa",a*b 匹配 "b";
- 非贪婪模式:(a+?)(a*b) 匹配 "aaab" 时,a+? 匹配 "a",a*b 匹配 "aab"。
Part4 串联与替换
4.1、串联
多个元素(含重复计数的元素)可直接串联,形成更长的正则表达式,匹配「各元素对应序列的串联结果」。
示例:a{2,3}b 匹配 "aab"、"aaab",不匹配 "ab"、"aaaab"。
4.2、替换(分支结构)
通过 | 分隔多个串联表达式,形成「分支结构」,匹配任意一个分支的结果。
语法差异:
- 除 basic/grep 外,均支持 | 分隔分支;
- grep/egrep 支持 \n 分隔分支。
匹配优先级:
- ECMAScript:「首次匹配」(选择第一个匹配的分支);
- 其他语法:「最长匹配」(选择匹配长度最长的分支)。
示例:ab|cd 匹配 "ab"、"cd",不匹配 "abd"、"acd"。
Part5 子表达式
子表达式是正则中的最小逻辑单元,其定义随语法不同而变化:
- basic/grep:子表达式是「串联表达式」(无分支);
- 其他语法:子表达式是「分支结构」(支持 | 分隔)。
Part6 语法支持功能汇总表
为方便对比各语法的功能支持情况,以下表格整理了核心元素在不同语法中的可用性(+ 表示支持)

Part7 语义
定位点可匹配目标字符串中的位置,而不匹配字符。 ^ 可匹配目标字符串的开头,而 $ 可匹配目标字符串的末尾。
7.2、后向引用
向后引用是一个反斜杠,后跟十进制值 N。它与第 n 个捕获组的内容匹配。 N 的值不得超过反斜杠之前的捕获组数量。
在 basic 和 grep 中,N 的值由反斜杠之后的十进制数字决定。 在 ECMAScript 中,N 的值由紧跟在反斜杠之后的所有十进制数字决定。
因此,在 basic 和 grep 中,N 的值绝不会超过 9(即使正则表达式具有九个以上捕获组)。 在 ECMAScript 中,N 的值是无限的。
示例:
- ((a+)(b+))(c+)\3 可匹配目标序列 "aabbbcbbb"。 后向引用 \3 可匹配第三个捕获组中的文本,即 "(b+)"。 它不匹配目标序列 "aabbbcbb"。
- (a)\2 无效。
- (b(((((((((a))))))))))\10 在 basic 和 ECMAScript 中具有不同的含义。 在 basic 中,后向引用是 \1。 后向引用可匹配第一个捕获组的内容(即分别以 (b 开头和最后一个 ) 结尾且位于后向引用之前的捕获组),最后的 0 可匹配普通字符 0。 在 ECMAScript 中,后向引用是 \10。 它可匹配第十个捕获组,即最里面的捕获组。
7.3、括号表达式
括号表达式用于定义一个字符和排序规则元素集合。 当括号表达式以字符 ^ 开头时,如果集合中没有元素与目标序列中的当前字符匹配,即表示匹配成功。 其他情况下,如果集合的任意元素与目标序列中的当前字符匹配,即表示匹配成功。
字符集可以通过列出单个字符、字符值域、字符类、等价类和排序规则符号的任意组合来定义。
7.4、捕获组
捕获组用于将其内容标记为正则表达式语法中的一个单元,并对与其内容相匹配的目标文本设置标签。 与每个捕获组相关联的标签是一个数字,此数字由用于标记捕获组的左括号计数来决定,一直计数到(包括)用于标记当前捕获组的左括号。 在此实现中,最大捕获组数量为 31。
示例:
- ab+ 可匹配目标序列 "abb",但不匹配目标序列 "abab"。
- (ab)+ 不匹配目标序列 "abb",但可匹配目标序列 "abab"。
- ((a+)(b+))(c+) 可匹配目标序列 "aabbbc" 并将捕获组 1 与子序列 "aabbb" 相关联,将捕获组 2 与子序列 "aa" 相关联,将捕获组 3 与 "bbb" 相关联,并将捕获组 4 与子序列 "c" 相关联。
7.5、字符类
括号表达式中的字符类用于将命名类中的所有字符都添加到括号表达式所定义的字符集。 若要创建字符类,请使用 [:,后跟字符类的名称,然后再跟 :]。
在内部,字符类名称通过调用 id = traits.lookup_classname 来识别。 如果 ch 返回 TRUE,则字符 traits.isctype(ch, id) 属于这样的类。 默认的 regex_traits 模板支持下表中的类名称。

7.6、字符范围
括号表达式中的字符值域用于将值域内的所有字符都添加到括号表达式所定义的字符集。 若要创建字符范围,请将字符 '-' 放在范围内第一个和最后一个字符之间。 字符范围可以将大于或等于第一个字符的数值、小于或等于最后一个字符的数值的所有字符都放在集合内。 请注意,这一添加的字符集取决于平台特定的字符表示法。 如果字符 '-' 位于括号表达式的开头或末尾,或者是字符范围的第一个或最后一个字符,则它表示其本身。
示例:
- [0-7] 表示字符集 { 0, 1, 2, 3, 4, 5, 6, 7 }。 它可匹配目标序列 "0"、"1",以此类推,但不匹配 "a"。
- 在采用 ASCII 字符编码的系统上,[h-k] 表示字符集 { h, i, j, k }。 它可匹配目标序列 "h"、"i",以此类推,但不匹配 "\x8A" 或 "0"。
- 在采用 EBCDIC 字符编码的系统上,[h-k]表示字符集 {h,i,'\x8A','\x8B','\x8C','\x8D','\x8E','\x8F','\x90',j,k}(h编码为0x88,k编码为0x92)。 它可匹配目标序列"h"、"i"、"\x8A",以此类推,但不匹配"0"。
- [-0-24]表示字符集 { -, 0, 1, 2, 4 }。
- [0-2-]表示字符集 { 0, 1, 2, - }。
- 在使用 ASCII 字符编码的系统上, [+--] 表示字符 { + , - }集。
但是,当使用区分区域设置的值域时,值域内的字符由区域设置的排序规则来决定。 排在值域定义第一个字符之后、值域定义最后一个字符之前的字符位于集合中。 这两个端字符也位于集合中。
7.7、排序规则元素
排序规则元素是一个当做单个字符来处理的多字符序列。
括号表达式中的排序规则符号用于将排序规则元素添加到括号表达式所定义的集合。 若要创建排序规则符号,请使用 [.,后跟排序规则元素,然后再跟 .]
7.8、控件转义序列
控件转义序列包含一个反斜杠,后跟字母 'c',然后再跟 'a' 到 'z'(或 'A' 到 'Z')之间的一个字母。 它可匹配由该字母命名的 ASCII 控制字符。 例如,"\ci" 可匹配目标序列 "\x09",因为 Ctrl+I 的值为 0x09。
7.9、dsw 字符转义
如下表所示,dsw 字符转义是字符类的短名称。

*ASCII 字符集
7.10、等价类
括号表达式中的等价类用于将与等价类定义中的排序规则元素等效的所有字符和排序规则元素全部添加到括号表达式所定义的集合。
若要创建等价类,请使用 [=,后跟排序规则元素,然后再跟 =]。 在内部,如果 elt1,则两个排序规则元素 elt2 和 traits.transform_primary(elt1.begin(), elt1.end()) == traits.transform_primary(elt2.begin(), elt2.end()) 等效。
7.11、文件格式转义
文件格式转义由通常的 C 语言字符转义序列 \\、\a、\b、\f、\n、\r、\t 和 \v 组成。 它们具有普通的含义,即分别表示反斜杠、警报符、退格符、换页符、换行符、回车符、水平制表符和垂直制表符。 在 ECMAScript 中,不允许使用 \a 和 \b。 (允许使用 \\,但它是一种标识转义,而不是一种文件格式转义)
7.12、十六进制转义序列
十六进制转义序列包含一个反斜杠,后跟字母 x,然后再跟两个十六进制数字 (0-9a-fA-F)。 它可匹配目标序列中与这两个数字所指定的值相等的字符。
例如,当采用 ASCII 字符编码时,"\x41" 可匹配目标序列 "a"。
7.13、标识转义
标识转义包含一个反斜杠,后跟单个字符。 它可匹配该字符。 当字符具有特殊含义时,需要用到它。 使用标识转义会移除特殊含义。 例如:
- a* 可匹配目标序列 "aaa",但不匹配目标序列 "a*"。
- a\* 不匹配目标序列 "aaa",但可匹配目标序列 "a*"。
如下表所示,标识转义中允许使用的字符集取决于正则表达式语法。

7.14、单个字符
括号表达式中的单个字符用于将该字符添加到括号表达式所定义的字符集。 当位于括号表达式中除开头外的任意位置时,^ 表示其本身。
示例:
- [abc] 可匹配目标序列 "a"、"b" 和 "c",但不匹配序列 "d"。
- [^abc] 可匹配目标序列 "d",但不匹配目标序列 "a"、"b" 或 "c"。
- [a^bc] 可匹配目标序列 "a"、"b"、"c" 和 "^",但不匹配目标序列 "d"。
在除 ECMAScript 之外的任何正则表达式语法中,如果 ] 紧跟在左括号 [ 之后或紧跟第一个 ^ 之后,则该字符表示其本身。
示例:
- []a 无效,因为没有 ] 来结束括号表达式。
- []abc] 可匹配目标序列 "a"、"b"、"c" 和 "]",但不匹配目标序列 "d"。
- [^]abc] 可匹配目标序列 "d",但不匹配目标序列 "a"、"b"、"c" 或 "]"。
在 ECMAScript 中,请在括号表达式中使用 \] 来表示字符 ]。
示例:
- []a 可匹配目标序列 "a",因为括号表达式为空。
- [\]abc] 可匹配目标序列 "a"、"b"、"c" 和 "]",但不匹配目标序列 "d"。
7.15、否定断言
否定断言可匹配除其内容外的任意项。 它不占用目标序列中的任何字符。
例如,(!aa)(a*) 可匹配目标序列 "a" 并将捕获组 1 与子序列 "a" 相关联。 它不匹配目标序列 "aa" 或目标序列 "aaa"。
如果目标字符串中的当前位置并非紧跟在字边界之后,则否定字边界断言匹配。
7.16、非捕获组
非捕获组用于将其内容标记为正则表达式语法中的一个单元,但不会对目标文本设置标签。
例如,(a)(?:b)*(c) 可匹配目标文本 "abbc",并将捕获组 1 与子序列 "a" 相关联,将捕获组 2 与子序列 "c" 相关联。
7.17、非贪婪重复
非贪婪重复将占用与模式匹配的目标序列的最短子序列。 贪婪重复将占用最长子序列。 例如,(a+)(a*b) 可匹配目标序列 "aaab"。
当使用非贪婪重复时,它会将捕获组 1 与目标序列开头的子序列 "a" 相关联,将捕获组 2 与目标序列末尾的子序列 "aab" 相关联。
当使用贪婪匹配时,它会将捕获组 1 与子序列 "aaa" 相关联,将捕获组 2 与子序列 "b" 相关联。
7.18、八进制转义序列
八进制转义序列包含一个反斜杠,后跟一个、两个或三个八进制数字 (0-7)。 它可匹配目标序列中与这些数字所指定的值相等的字符。 如果数字全部为 0,则序列无效。
例如,当采用 ASCII 字符编码时,\101 可匹配目标序列 "a"。
7.19、普通字符
普通字符是在当前语法中没有特殊含义的任何有效字符。
在 ECMAScript 中,下列字符具有特殊含义:
^ $ \ . * + ? ( ) [ ] { } |
在 basic 和 grep 中,下列字符具有特殊含义:
.[ \
此外,在 basic 和 grep 中,当在特定上下文中使用下列字符时,它们具有特殊含义:
- 除下列情况外,* 在所有情况下均具有特殊含义:它是正则表达式中的第一个字符或紧跟在正则表达式中第一个 ^ 之后,或者,它是捕获组的第一个字符或紧跟在捕获组中第一个 ^ 之后。
- 当 ^ 是正则表达式的第一个字符时,它具有特殊含义。
- 当 $ 是正则表达式的最后一个字符时,它具有特殊含义。
在 extended、egrep 和 awk 中,下列字符具有特殊含义:
.[ \ ( * + ? { |
此外,在 extended、egrep 和 awk 中,当在特定上下文中使用下列字符时,它们具有特殊含义。
- 当 ) 与前面的 ( 匹配时,它具有特殊含义
- 当 ^ 是正则表达式的第一个字符时,它具有特殊含义。
- 当 $ 是正则表达式的最后一个字符时,它具有特殊含义。
普通字符可匹配目标序列中的相同字符。 默认情况下,如果两个字符由相同的值表示,即表示匹配成功。 在不区分大小写的匹配中,如果 ch0,则两个字符 ch1 和 traits.translate_nocase(ch0) == traits.translate_nocase(ch1) 匹配。 在区分区域设置的匹配中,如果 ch0,则两个字符 ch1 和 traits.translate(ch0) == traits.translate(ch1) 匹配。
7.20、肯定断言
肯定断言可匹配其内容,但不占用目标序列中的任何字符。
示例:
- (=aa)(a*) 可匹配目标序列 "aaaa" 并将捕获组 1 与子序列 "aaaa" 相关联。
- (aa)(a*) 可匹配目标序列 "aaaa",并将捕获组 1 与目标序列开头的子序列 "aa" 相关联,将捕获组 2 与目标序列末尾的子序列 "aa" 相关联。
- (=aa)(a)|(a) 可匹配目标序列 "a",并将捕获组 1 与空序列相关联(因为肯定断言失败),将捕获组 2 与子序列 "a" 相关联。 它还可匹配目标序列 "aa",并将捕获组 1 与子序列 "aa" 相关联,将捕获组 2 与空序列相关联。
7.21、Unicode 转义序列
unicode 转义序列包含一个反斜杠,后跟字母 'u',然后再跟四个十六进制数字 (0-9a-fA-F)。 它与具有由四个数字指定的值的目标序列中的字符匹配。 例如,当采用 ASCII 字符编码时,\u0041 可匹配目标序列 "a"。
7.22、通配符
通配符可匹配目标表达式中除换行符外的任何字符。
7.23、字边界
字边界在以下情况下出现:
- 当前字符位于目标序列的开头,并且是单词字符 A-Za-z0-9_ 之一
- 当前字符位置超出目标序列的末尾,并且目标序列中的最后一个字符为一个单词字符。
- 当前字符是一个单词字符,而前面的字符不是。
- 当前字符不是一个单词字符,而前面的字符是。
7.24、字边界断言
当目标字符串中的当前位置紧跟在字边界之后时,字边界断言即匹配。
Part8 匹配和搜索
若要正则表达式与目标序列相匹配,整个正则表达式必须匹配整个目标序列。 例如,正则表达式 bcd 可匹配目标序列 "bcd",但不匹配目标序列 "abcd",也不匹配目标序列 "bcde"。
若要成功执行正则表达式搜索,目标序列中的某个位置必须具有与正则表达式相匹配的子序列。 搜索通常会从左到右查找最匹配的子序列。
示例:
- 在目标序列 "bcd" 中搜索正则表达式 bcd 可以成功,并会匹配整个序列。 在目标序列 "abcd" 中进行相同的搜索也可以成功,并会匹配后三个字符。 在目标序列 "bcde" 中进行相同的搜索也可以成功,并会匹配前三个字符。
- 在目标序列 "bcdbcd" 中搜索正则表达式 bcd 可以成功,并会匹配前三个字符。
当在目标序列中的某些位置具有多个匹配的子序列时,可通过两种方式来选择匹配的模式。
第一匹配将选择与正则表达式匹配时第一个找到的子序列。
最长匹配将从在该位置匹配的子序列中选择最长的一个。 如果最长的子序列不止一个,则最长匹配方法将选择第一个找到的子序列。
例如,如果使用首次匹配方法,则在目标序列 "abcd" 中搜索正则表达式 b|bc 时会匹配子序列 "b",因为分支结构的左侧搜索词与该子序列匹配;因此,首次匹配方法不会尝试匹配分支结构的右侧搜索词。 当使用最长匹配方法时,进行同样的搜索会匹配 "bc",因为 "bc" 比 "b" 要长。
如果匹配到达目标序列的末尾而未失败,则部分匹配成功(即使尚未到达正则表达式的末尾)。 因此,在部分匹配成功后,目标序列的附加字符可能会导致之后的部分匹配失败。 但是,在部分匹配失败后,目标序列的附加字符不可能会导致之后的部分匹配成功。 例如,在部分匹配时,ab 可匹配目标序列 "a",但不匹配 "ac"。
格式标志

常见正则表达式语法

示例代码
1. 使用 regex_match 完全匹配
string s = "abc123";
regex pattern("[a-z]+\\d+"); // 小写字母 + 数字
if (regex_match(s, pattern)) {
cout << "完全匹配成功" << endl;
} else {
cout << "匹配失败" << endl;
}
2. 使用 regex_search 局部匹配
string s = "hello 123 world";
regex pattern("\\d+"); // 匹配数字
smatch result;
if (regex_search(s, result, pattern)) {
cout << "找到数字:" << result.str() << endl;
}
3. 使用 regex_replace 字符替换
string s = "abc123xyz456";
regex pattern("\\d+"); // 匹配数字
string replaced = regex_replace(s, pattern, "#");
cout << replaced << endl; // 输出:abc#xyz#
4. 捕获多个子匹配
string s = "Name: John, Age: 25";
regex pattern("Name: (\\w+), Age: (\\d+)");
smatch match;
if (regex_search(s, match, pattern)) {
cout << "姓名:" << match[1] << endl;
cout << "年龄:" << match[2] << endl;
}
5. 匹配邮箱格式示例
string email = "user123@example.com";
regex pattern("[\\w.-]+@[\\w.-]+\\.[a-zA-Z]{2,}");
if (regex_match(email, pattern)) {
cout << "邮箱格式合法" << endl;
} else {
cout << "邮箱格式错误" << endl;
}
匹配模式(flag)
正则对象可以设置模式:
regex pattern("abc", regex_constants::icase); // 忽略大小写
常用标志位:

性能提示
regex在 C++11 初期实现性能一般,现代编译器已优化。- 对于频繁匹配,可复用
std::regex对象,避免重复构造。 - 若性能要求极高,可考虑
RE2等替代库(Google)。
综合实战示例
1、日志过滤:提取指定格式的日志(如错误信息)
目标:从日志中提取 [ERROR] 级别的信息
#include <iostream>
#include <regex>
#include <string>
#include <vector>
using namespace std;
int main() {
vector<string> logs = {
"[INFO] 2025-07-14 Connection established",
"[ERROR] 2025-07-14 Disk not found",
"[WARN] 2025-07-14 High memory usage",
"[ERROR] 2025-07-14 Timeout occurred"
};
regex error_pattern(R"(\[ERROR\]\s+(\d{4}-\d{2}-\d{2})\s+(.*))");
for (const auto& log : logs) {
smatch match;
if (regex_match(log, match, error_pattern)) {
cout << "日期: " << match[1] << ", 错误信息: " << match[2] << endl;
}
}
return 0;
}
输出:
日期: 2025-07-14, 错误信息: Disk not found
日期: 2025-07-14, 错误信息: Timeout occurred
2、文件名匹配:匹配特定后缀的文件(如 .txt、.log)
#include <iostream>
#include <regex>
#include <vector>
using namespace std;
int main() {
vector<string> filenames = {
"report.txt", "data.csv", "log_2025.log", "notes.TXT", "script.cpp"
};
regex txt_log_pattern(R"((.*)\.(txt|log))", regex_constants::icase); // 忽略大小写
cout << "匹配的文件名:" << endl;
for (const auto& name : filenames) {
if (regex_match(name, txt_log_pattern)) {
cout << " " << name << endl;
}
}
return 0;
}
输出:
匹配的文件名:
report.txt
log_2025.log
notes.TXT
3、表单验证:验证邮箱、手机号、密码强度
邮箱验证
string email = "test_user-123@example.co.uk";
regex email_pattern(R"([\w\.-]+@[\w\.-]+\.[a-zA-Z]{2,})");
cout << (regex_match(email, email_pattern) ? "邮箱合法" : "邮箱非法") << endl;
手机号验证(中国大陆)
string phone = "13812345678";
regex phone_pattern(R"(1[3-9]\d{9})"); // 以1开头 + 合法段位 + 9位数字
cout << (regex_match(phone, phone_pattern) ? "手机号合法" : "手机号非法") << endl;
密码强度验证(8~16位,包含字母和数字)
string password = "Abc12345";
regex pwd_pattern(R"((?=.*[A-Za-z])(?=.*\d)[A-Za-z\d]{8,16})");
cout << (regex_match(password, pwd_pattern) ? "密码合法" : "密码不合法") << endl;
3843

被折叠的 条评论
为什么被折叠?



