🥦正则表达式
2022-6-20
| 2023-8-2
0  |  阅读时长 0 分钟
type
status
date
slug
summary
tags
category
icon
password
Property
 
正则表达式是一种描述字符序列的方法。C++11中有正则表达式库(RE库),定义在头文件regex
regex库组件:
notion image
 
regex类表示一个正则表达式,它支持的一些操作:
notion image
在定义或赋值一个regex时,可以指定一些标志位影响regex如何匹配,上图中最后六个即为编写正则表达式时所用的语言,默认为ECMAScript,即ECMA-262语法标准,这也是很多Web浏览器所使用的。
 
函数regex_matchregex_search确定一个给定字符序列与一个给定regex是否匹配:
  • 整个输入序列与表达式匹配,regex_match返回true
  • 输入序列中一个子串与表达式匹配,regex_search返回true
 
notion image
 
匹配文件名时忽略大小写:
在模式中,.有特殊含义,通常代表匹配任意字符,于是需要使用反斜线使模式中的点去掉特殊含义,但C++语言中的反斜线也有特殊含义,于是需要另一个反斜线去除特殊含义,在正则表达式串中,\\.表示字符.
 
 
正则表达式的语法检查是在运行时解析的。如果编写的正则表达式有错误,运行时标准库会抛出regex_error类型的异常。regex_error也有一个说明异常情况的what成员,用以描述错误,它还有一个code成员,返回某个错误类型对应的数值编码,这是由具体实现定义的:
以下为正则表达式全部错误类型,regex_error类的code成员返回下表从上到下,从0开始的错误编号:
notion image
 
正则表达式对象的创建和赋予新值是很慢的,尽量避免创建很多不必要的regex,如在循环外定义regex而不是循环内。
匹配的输入序列中的的字符可以是charwchar_t,字符可保存在string(wstring)char(wchar_t)数组中。regex类保存char编写的正则表达式,wregex类保存wchar_t编写的正则表达式,两者操作完全相同。
 
 
 
match的类型必须与输入序列类型相匹配:
  • smatch保存string类型输入序列的结果
  • cmatch保存字符数组类型输入序列的结果
  • wsmatch保存wstring类型输入序列的结果
  • wcmatch保存宽字符数组类型输入序列的结果
类型匹配关系:
notion image
上例匹配拼写错误的单词时,只找到了序列中第一个匹配的子串,可以用sregex_iterator来获得string中所有匹配。regex迭代器是一种迭代器适配器,被绑定到一个regex和一个输入序列上。
 
sregex_iterator操作:
notion image
notion image
上表中的解引用it和对it使用箭头运算符文本说明有问题,解引用返回的是smatch对象,而箭头运算符调用该smatch对象的成员。
sregex_iterator绑定到stringregex对象时,迭代器自动定位到string中第一个匹配位置,即构造函数会调用一次regex_search。解引用会得到最近一次匹配的结果。递增迭代器会查找下一个匹配的结果。
 
找出所有不符合拼写规则的单词:
sregex_iterator的默认构造函数创建一个类似尾后迭代器的对象。
 
有时还需要获得匹配位置的上下文内容,一个(s|c|ws|wc)match类型对象还有两个名为prefix和suffix的成员函数,它们的返回类型为(s|c|ws|wc)sub_match,功能为保存上下文的相关内容。而sub_match对象也有两个成员,分别为str和length,表示上下文文本和文本长度,使用它:
 
 
smatch的操作:
notion image
正则表达式的模式中通常包含一个或多个子表达式,它是模式的一部分。语法上用括号表达子表达式:
以上模式包含两个括号括起来的子表达式:
  1. ([[:alnum:]]+)匹配一个或多个字符的序列
  1. (cpp|cxx|cc)匹配文件扩展名
 
可以只打印文件名:
match对象的str成员函数的参数为0时,表示整个模式串的匹配结果。而1表示第一个子表达式。
 
 
 
 
使用子表达式例子:美国电话号码有10位,包含3位区号和7位本地号,区号通常放在括号里,但这并不是必须的。剩余7位数字可以用短横线’-’、一个点’.‘或一个空格’ ‘分隔成3个和4个数字,但也可以完全不用分隔符。区号和本地号之间也可以用短横线’-’、一个点’.‘或一个空格’ '分隔成3个和4个数字,但也可以完全不用分隔符。我们希望识别出这种格式的数据,通过分两步实现,第一步先找出可能是电话号码的序列,第二步再调用一个函数完成验证。
ECMAScript正则表达式语言的一些语法:
  • \d表示单个数字,\d{n}表示一个n个数字的序列
  • 方括号中的字符集表示匹配其中的任一个。[-. ]匹配短横线’-’、一个点’.‘或一个空格’ ‘
  • 后接?的组件是可选的。[-. ]?表示可以有短横线’-’、一个点’.‘或一个空格’ ',也可以什么都没有
  • ECMAScript使用反斜线\表示一个字符本身而非它的特殊含义
 
于是电话号码匹配模式串为:
 
但最后可能区号的括号只有一半,这时候需要第二步检查可能的号码是否合法。
子匹配操作:
notion image
电话号码匹配程序的模式有7个子表达式,因此,smatch对象包含8个ssub_match元素,0为整个匹配,1~7表示对应的子表达式。
调用valid时,已经知道有一个完整的匹配,但不知道每个可选的子表达式是否是匹配的一部分,如果是,则该子表达式的matched成员为true。
valid函数:
注:match对象的str(n)是直接获取第n个子表达式的文本,而match[n]获取的是第n个子表达式对应的sub_match对象。
 
regex_replace函数可以将匹配到的内容替换为其他内容:
notion image
将号码生成为特定形式:
标准库定义了在替换过程中控制匹配或格式的标志,它可以传给函数的mft参数:
notion image
上表这些控制标志的类型为match_flag_type,这些值定义在regex_contents命名空间中,此命名空间在std命名空间中,为使用regex_constants中的名字:
默认,regex_replace输出整个输入序列,未与正则表达式匹配的部分会原样输出,匹配的部分按fmt指定的格式输出,可以通过使用格式标志改变它:
 
  • C++
  • bitset 类型随机数
    目录