欢迎光临散文网 会员登陆 & 注册

十五、C++正则表达式

2023-04-04 19:28 作者:努力赚钱养朵朵  | 我要投稿


正则表达式的核心在于用一个字符串(模式串)来描述、匹配一系列符合某个句法规则的字符串(待匹配串)。正则表达式中可以包含普通或者特殊字符,特殊字符可以影响正则表达式的解释。可以用在线网站验证写的正则表达式是否能正确匹配,如:http://www.jsons.cn/reg/

正则表达式中常用的特殊字符

表15-1 按次数匹配子表达式和首尾字串匹配

表15-1 正则表达式的常用特殊字符

◉ */+/?三个字符可以合并记忆为匹配子表达式0+、1+、01次;

◉ ^/$可以合并记忆为匹配字符串头尾。


 次数区间表示(续表15-1)

表15-1 正则表达式中的常见特殊字符(续1)

◉ 次数区间匹配,匹配区间内的数值次。


 非贪婪匹配和转义(续表15-1)

表15-1 正则表达式中的常见特殊字符(续2)

◉ ?在特殊字符后表示为非贪婪匹配,即取特殊字符表示的最小的条件;

◉ \为转义字符,用于转义表达式中的特殊字符,即匹配特殊字符本身。


按集合内容匹配(续表15-1)

表15-1 正则表达式中的常见特殊字符(续3)

◉ 除了字符范围的表达外,“[]”集合中的每一个元素(而非每一个子集,要注意)都会被匹配。


“或匹配”和子表达式的表示(续表15-1)

表15-1 正则表达式中的常见特殊字符(续4)

◉ 使用字符“|”需要注意的是其类似逻辑运算“||”的分支优先特点,即出现表达式值为真就返回。

◉ 括号表示子表达式可以方便获取匹配结果(存至smatch)。


“\”加字母形式的特殊字符匹配(续表15-1)

表15-1 正则表达式中的常见特殊字符(续5)

◉ 其中最常用的是【\d、\D、\w、\W】,分别用于匹配(非)数字以及(非)数字和字母。


C++的正则表达式库——regex

regex类表示一个正则表达式。表15-2列出了regex支持的操作。

表15-2 regex类的操作

表15-2 regex类的操作

定义regex时指定的标志(续表15-2)

表15-2 regex类的操作(续1)

在C++语言中,通常需要将一个正则表达式存储在一个字符串字面值常量中再赋值给regex对象,其中需要留意对特殊字符本身的转义。

特别注意(记住),正则表达式中的一个“\”,在C++字面值常量中需要2个“\”来表示。例如:为了匹配“.”,因其可以表示特殊字符,因此需要对其转义,应该写作“\.”,但是“\”本身具有转义的含义,因此又应该对“\”再转义,所以最终得到的字面值常量字符串为“\\.”。

C++正则表达式的匹配、查找、替换

C++提供了regex_match函数实现正则表达式的匹配功能;提供了regex_search函数实现正则表达式的查找功能;提供了regex_replace函数实现正则表达式的替换功能。具体解释见表15-3。

表15-3

◉ match是整个、search是部分,返回匹配到与否的布尔值。

子表达式与smatch

        正则表达式可以捕获到匹配的子串。这通常通过“( )”模式串和smatch类型来实现。

        通常把“( )”构成的表达式称为子表达式。smatch是一个容器类型,它存储的元素类型是ssub_match,负责保存子表达式匹配的结果,它通常会传递给regex_search或regex_match函数作为参数。

        smatch 对象除了提供匹配整体的相关信息外,还提供访问每个子表达式匹配结果的能力。子表达式的匹配结果是按位置来访问的。第一个子匹配位置为0,表示整个模式对应的匹配,然后按子表达式在整个表达式中出现的顺序给出每个子表达式对应的匹配。表15-4列举了smatch类型支持的操作。

表15-4

◉ m.prefix()和m.suffix()一般只在regex_search中使用(regex_match是匹配整个序列)。

        在regex_replace中的参数fmt中,可以将“$”和一个非负整数连接起来,来表示匹配的子串。例如:fmt中“$1”表示匹配的第一个子串...特殊的是,“$0”表示匹配的整个字符串。


regex迭代器

有时可能需要逐一遍历待匹配串中与某个模式串匹配的所有字串,如果此时仅用regex_search会使代码显得冗余。因此C++提供了regex迭代器类型sregex_iterator来获得所有匹配的子串,它被绑定到一个输入序列和一个regex对象上。初学阶段,可以认为sregex_iterator指向的就是调用regex_search函数匹配成功后得到的smatch对象。这种迭代器操作如表15-5所示。

表15-5

◉ 由于sregex_iterator指向的就是ssub_match对象,因此获取了匹配成功的sregex
_iterator,你就可以通过迭代器调用表15-4中列举的smatch对象支持的操作。

下例展示了如何使用sregex_iterator实现类似stringstream的字符串分割:


十五、C++正则表达式的评论 (共 条)

分享到微博请遵守国家法律