1. 正则表达式初步
Posted by haifeng on 2023-12-24 14:55:17 last update 2024-10-12 16:16:12 | Answers (0) | 收藏
自 C++11 开始, C++ 通过标准库 提供对正则表达式的支持. 因此, 如要使用正则表达式, 则在程序开始, 加入下面这一行.
#include "regex"
(上面两个 " 分别改为小于号和大于号.)
C++11 使用 ECMAScript 语法作为正则表达式的默认语法. ECMAScript 虽简单, 但它提供了强大的正则表达式功能.
验证正则表达式
推荐使用 DevToys 验证正则表达式.
字面匹配
a 匹配 a, B 匹配 B 等等. 即按照字面上的字符匹配.
可以字面匹配的字符称为“元字符”. 元字符包括 26个英文字母(包括大小写) 斜杠 /
范围指定
模式字符串 | 涵义 |
---|---|
[] | 范围界定符, 如果要匹配字符'['或']', 则加上转义字符\, 即 \[ 匹配'['. 但是在 C++ 中要使用 \\[ |
- | 范围符, 如果要匹配字符'-', 则加上转义符\, 即 \- 匹配 '-'. 在 C++ 中要使用 \\- |
. | 匹配单个字符, 如果要匹配'.', 则要加转义符'\', 即 \. 匹配'.'; 或者使用[.]匹配. |
\\ | 匹配转义字符 \ |
\d | 匹配单个数字字符, 即匹配0,1,2,...,9 中的一个. |
[a-z] | 匹配单个小写字符, 即范围在 a 到 z 这26个小写字母之间. (可以认为这是一个变量 x, $x\in\{a,b,c,d,\ldots,x,y,z\}$) |
[A-Za-z0-9] | 匹配单个字符 x, 其中 $x\in\{A,B,C,\ldots,Z,a,b,c,\ldots,z,0,1,2,\ldots,9\}$ |
a[a-z] 匹配 "ab", "aa", "az" 等字符串.
重复模式
模式字符串 | 涵义 |
---|---|
+ | 重复1次或多次. (重复 $n$ 次, $n\geqslant 1$.) |
* | 重复0次或多次. (重复 $n$ 次, $n\geqslant 0$.) |
? | 重复0次或1 次. (重复 $n$ 次, $n=0$ 或 $n=1$.) |
例子:
[a-z]* 匹配一个空字符串或由 a 到 z 组成的任意字符串.
分组符号 ()
分组符号() 可以将某几个字符作为一个整体.
例: (Xyz)+ 将匹配 Xyz, XyzXyz, XyzXyzXyz 等等.
例 1. 匹配文件名. 文件名形如 filename.abc, 小数点前面的字符串称为前缀, 后面的字符串称为后缀.
如果对文件名长度不作要求, 但必须有小数点, 则可以设置模式字符串为:
char regex_filename[]="[a-zA-Z_][a-zA-Z_0-9]*\\.[a-zA-Z0-9]+";
这里前缀遵循这样的规则, 以字母或下划线开头, 中间可以有数字, 不能含有其他字符.
如果是 MS-DOS 系统下的文件名, 则要求前缀长度在 $[1,8]$ 之间, 后缀的长度在 $[1,3]$ 之间.
例 2. 匹配正整数.
char regex_positiveInt[]="[1-9][0-9]*";
如果允许 +9 这样的形式, 则
char regex_positiveInt[]="[+]?[1-9][0-9]*";
例3. 匹配非负整数.
即形如 0,1, +9, +0 等, 但不能是 + 或 -, 至少出现一个数字.
char regex_nonpositiveInt[]="[+]?[0-9][0-9]*";
等价于
char regex_nonpositiveInt[]="[+]?[0-9]+";
例 4. 匹配整数.
整数包含正整数、零、负整数. +9 或 9 或 -9 都是允许的.
char regex_integer[]="[+-]?[0-9]+"
例 5. 匹配小数.
小数的形式有点像文件名, 只是其中的字符除小数点外只能是数字. 形如 -0.8
char regex_decimal[]="[+-]?[0-9]+[\\.][0-9]+";
这里我们规定小数点前必须要有数字. 如果允许 .8 或 -.8 这种形式的小数, 则模式字符串应设定为
char regex_decimal[]="[+-]?[0-9]*[\\.][0-9]+";
例 6. 匹配整数或小数
char regex_number[]="[+-]?[0-9]+[\\.][0-9]+|[+-]?[0-9]+";
这里使用了逻辑或 |
注意如果写成 "[+-]?[0-9]+[\\.]?[0-9]*", 则允许形如 8. 这样的字符串, 两者并不等价.
char regex_number[]="[+-]?[0-9]+[\\.]?[0-9]*"
例 2. 为输入 sin(x), x 是形如 "1/3pi", "2pi", "-2.5pi" 的字符串, 则
char regex_input[]="[+-]?\d+/\d+pi|[+-]?\d+pi|[+-]?\d+\.\d+pi";
但如果想要捕获pi前面的系数, 则需要将模式字符串分组,
char regex_input[]="([+-]?)(\d+)/(\d+)pi|([+-]?)(\d+)pi|([+-]?)(\d+\.\d+)pi";
可以在 DevToys 中测试该模式字符串, 但在 C++ 编程中要将反斜杠改为 \\ 即写为
char regex_input[]="([+-]?)(\\d+)/(\\d+)pi|([+-]?)(\\d+)pi|([+-]?)(\\d+\\.\\d+)pi";
这样对于输入的字符串 "2.3pi", 得到第6项为空字符串"", 第7项为 "2.3".
例子: 要求匹配形如 pi->calc(9) 这样的字符串.
([a-zA-Z]+)(->)([a-zA-Z]+)(\()([a-zA-Z0-9]*)(\))
References:
[1] C++ regex Tutorial: Regular Expressions In C++ With Examples (softwaretestinghelp.com)