Answer

问题及解答

正则表达式初步

Posted by haifeng on 2023-12-24 14:55:17 last update 2024-10-12 16:16:12 | Edit | 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)