C++Primer_Chap17_标准库特殊设施_List03_正则表达式_笔记

  正则表达式(regular expression)是一种描述字符序列的方法,是一种及其强大的计算工具。C++正则表达式库(RE库)定义在头文件regex中,包含多个组件:

正则表达式库组件
regex 表示有一个正则表达式的类,即regex类表示一个正则表达式
regex_match 将一个字符序列与一个正则表达式匹配
regex_search 寻求第一个与正则表达式匹配的子序列
regex_replace 使用给定格式替换一个正则表达式
sregex_iterator 迭代器适配器,调用regex_search来遍历一个string中所有匹配的子串
smatch 容器类,保存在string中搜索的结果
ssub_match string中匹配的子表达式的结果

  

regex_search和regex_match的参数
注意:这些操作返回bool值,指出是否找到匹配

(seq, m, r, mft)

(seq, r, mft )

在字符序列seq中查找regex对象r中的正则表达式。seq可以是一个string、表示范围的一对迭代器以及一个指向空字符结尾的字符数组的指针

m是一个match对象,用来保存匹配结果的细节。m和seq必须具有兼容的类型

mft是一个可选的regex_constants::match_flag_type值。

使用正则表达式库

  查找违反拼写规则“i除非在c之后,否则必须在e之前”的单词示例:

//查找不在字符c之后的字符串ei
string pattern("[^c]ei");

pattern = "[[:alpha:]]" + pattern + "[[:alpha:]]*";
regex r(pattern);    //构造一个用于查找模式的regex
smatch results;

string test_str = "receipt freind theif receive";

if( regex_search(text_str, results, r))
     cout << results.str() << endl;

  我们首先定义了一个string来保存希望查找的正则表达式。正则表达式[^c]表明我们希望匹配任一不是'c'的字符,而[^c]ei指出我们想要匹配这种字符后接ie的字符串。此模式描述的字符串恰好包含三个字符。我们想要包含此模式的单词的完整内容。为了与整个单词匹配,我们还需要一个正则表达式与这个三字母模式之前和之后的字母匹配。

  这个正则表达式包含0个或多个字母后接我们的三字母的模式,然后再接0个或多个额外的字母。默认情况下,regex使用的正则表达式语言是ECMAScript。在ECMAScript中,模式[[:alpha:]]匹配任一字母,符号+和*分别表示我们希望“1个或多个”或“0个或多个”匹配。因此[[::alpha:]]*将匹配0个或多个字母。

指定regex对象的选项

  当我们定义一个regex或是对一个regex调用assign为其赋予新值时,可以指定一些标志来影响regex如何操作。这些标志控制regex对象的处理过程。对于指出编写正则表达式所用语言的6个标志,我们必须设置其中一个,且只能设置一个。默认情况下,ECMAScript标志被设置,从而regex会使用ECMA-262规范,这也是很多Web浏览器所用的正则表达式语言。

regex和wregex选项

regex r(re)

regex r(re, f)

re表示一个正则表达式,它可以是一个string、一个表示字符范围的迭代对、一个指向空字符结尾的字符数组的指针、一个字符指针和一个计数器或是一个花括号包围的字符列表。

f是指出对象如何处理的标志。f通过下面列出的值来设置。如果未指定f,默认值为ECMAScript。

r1 = re

将r1中的正则表达式替换成re。

re表示一个正则表达式,它可以是另一个regex对象、一个string、一个指向空字符结尾的字符数组的指针或是一个花括号包围的字符列表。

r1.assign(re, f) 与使用赋值运算符(=)效果相同
r.mark_count() r中子表达式的数目
r.flags() 返回r的标志集
注:构造函数和赋值操作也可能抛出类型为regex_error的异常。
定义regex时指定的标志
定义在regex和regex_constants::synatax_option_type中
icase 在匹配过程中忽略大小写
nosubs 不保存匹配的子表达式
optimize 执行速度优先于构造速度
ECMAScript 使用ECMA-262指定的语法
basic 使用POSIX基本的正则表达式语法
extended 使用POSIX扩展的正则表达式语法
awk 使用POSIX版本的awk语言的语法
grep 使用POSIX版本的grep的语法
egrep

使用POSIX版本的egrep的语法

  一个正则表达式来识别扩展名的示例:

//1个或多个字母或数字字符后面接一个'.'再接"cpp"或"cxx"或"cc"
regex r("[[:alnum:]]+\\.{cpp|cxx|cc}$", regex::icase);
smatch results;
string filename;
while( cin >> filename)
    if( regex_search(filename, results, r))
        cout << results.str() << endl;

  在正则表达式语言中,字符点(.)通常匹配任意字符。与C++一样,可以在字符之前放置一个反斜线\来去掉其特殊含义。由于反斜线\也是C++中的一个特殊字符,我们在字符串常量中必须连续使用两个反斜线。

  一个正则表达式的语法是否正确是在运行时解析的。如果我们编写的正则表达式存在错误,则在运行时标准库会抛出一二类型为regex_error的异常。类似标准库异常类型,regex_error有一个描述发生什么错误的what操作,和一个返回错误类型对应的数值编码的code成员。

try{
    regex r("[[:alnum:]+\\.(cpp|cxx|cc)$", regex::icase);
}catch (regex_error e)
{
    cout << e.what() << "\ncode:" << e.code() << endl;
}

猜你喜欢

转载自blog.csdn.net/accumulating_mocai/article/details/83931581