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