C++ 正则表达式.docx
- 文档编号:4914414
- 上传时间:2022-12-11
- 格式:DOCX
- 页数:13
- 大小:98.66KB
C++ 正则表达式.docx
《C++ 正则表达式.docx》由会员分享,可在线阅读,更多相关《C++ 正则表达式.docx(13页珍藏版)》请在冰豆网上搜索。
C++正则表达式
什么是正则表达式?
正则表达式是一种用来描述一定数量文本的模式。
Regex代表RegularExpress.
如果您不知道什么是正则表达式,请看这篇文章
有了正则表达式的基础,问题是如何使用。
我们以boost:
:
regex来说
先看一个网上经典的例子。
#include"stdafx.h"
#include
#include
#include
#include
#include
usingnamespacestd;
usingnamespaceboost;
regexexpression("^select([a-zA-Z]*)from([a-zA-Z]*)");
intmain(intargc,char*argv[])
{
std:
:
stringin;
cmatchwhat;
cout<<"enterteststring"< getline(cin,in); if(regex_match(in.c_str(),what,expression)) { for(inti=0;i cout<<"str: "< } else { cout<<"ErrorInput"< } return0; } 结果 输入: selectnamefromtable 输出: str: selectnamefromtable str: name str: table 按照我们的要求,字符串被匹配挑出来了。 这在处理大量规则的文本格式的时候很有用,因为它很灵活,一通百通。 首先,即使你拥有了boost库,也需要单独编译regex. 如果你不知道boost库,看这里http: //www.stlchina.org/twiki/bin/view.pl/Main/BoostStartIntroduce 网上的介绍: boost库安装比较麻烦,需要自己编译源文件,我整理了一下,如果仅仅需要做正则表达式,按下面的代码敲就行了: cmd vcvars32.bat cdD: \boost_1_32_0\libs\regex\build d: nmake-fvc6.mak nmake-fvc6.makinstall 注意,别看下载下来的数据包没有多大,解压缩之后达到了100多M,编译完之后为109M,占用131M,所以安装时一定注意空出足够的空间,敲入nmake-fvc6.mak后等待的时间比较长,屏幕上还会出现一大堆英语,可以不做考虑。 按照步骤往下敲就行了。 压缩包内文档很详细,参照文档继续就可以了。 在VC6中集成: Tools->Options->Directories->Includefiles 加入: D: \boost_1_32_0 我用的是VS2003做了run.bat chdirE: \Program\boost_1_34_1 bjam"-sTOOLS=vc-7_1""-sVC71_ROOT=D: \ProgramFiles\MicrosoftVisualStudio.NET2003\Vc7" "——prefix=E: \Program\boost""——builddir=E: \Program\boost_1_34_1\build""-sBUILD=debugrelease PAUSE 至于参数,需要参考boost安装介绍 其他的一些介绍 boolvalidate_card_format(conststd: : strings) { staticconstboost: : regexe("(\\d{4}[-]){3}\\d{4}"); returnregex_match(s,e); } boost: : regex的默认正则表达式语法是perl语法 boost: : regex支持perlregular表达式、POSIX-Extendedregular表达式和POSIX-BasicRegular表达式,但默认的表达式语法是perl语法,如果要使用其余两种语法需要在构造表达式的时候明确指定。 例如,下面两种方法效果相同 //e1isacasesensitivePerlregularexpression: //sincePerlisthedefaultoptionthere''snoneedtoexplicitlyspecifythesyntaxusedhere: boost: : regexe1(my_expression); //e2acaseinsensitivePerlregularexpression: boost: : regexe2(my_expression,boost: : regex: : perl|boost: : regex: : icase); perl正则表达式语法 perl正则表达式语法可参见《perl语言入门》第7、8、9章或boost的文档。 这里列出的语法是不全面的,而且部分说明可能并不清楚。 。 任意字符;使用match_no_dot_null标志时不匹配NULL字符;使用match_not_dot_newline时不匹配换行字符 ^匹配行的开始 $匹配行的结束 *重复零次或则更多,例如a*b可匹配b,ab,aab,aaaaaaab +重复一次以上,例如a+b可匹配ab,aab,aaaaaaaab.但不能匹配b了 ? 零次或则一次,例如ca? b匹配cb,cab但不匹被caab a{n}匹配字符''a''重复n次 a{n,},字符a重复n次以上(含n次) a{n,m}a重复n到m次(含) *? 匹配前一个原子零次以上 +? 匹配前一个原子一次以上 ? ? 匹配前一个原子零次以上 {n,}? 匹配前一个原子n次以上(含) -? [0-9.]+) {n,m? 匹配前一个原子n到m次(含) |或操作,例如ab(d|ef)匹配abd或则abef []字符集操作,例如[abc]将匹配任何单个字符''a'',''b'',''c'' [a-d],表示a、b、c、d ^否操作,例如[^a-c]表示a至c之外的所有字符 boost: : regex对unicode编码的支持 boost: : regex使用ICU来实现对unicode及unicode变种的支持,这需要在编译boost的时候指出是否使用ICU以及ICU所在的目录。 否则编译出来的boost: : regex不支持unicode编码。 其中boost: : wregex支持unicode编码的搜索,如果要搜索UTF-8、UTF-16、UFT-32编码的字符串,则要用boost: : u32regex.注意boost: : wregex只能支持unicode编码,不能支持uft编码。 搜索时如何忽略大小写 如果要在搜索时忽略大小写(即大小写不敏感),则要用到表达式选项boost: : regex: : icase,例如: boost: : regexe2(my_expression,boost: : regex: : perl|boost: : regex: : icase); 模板类: l basic_regex 用来保存一个“正则表达式”的类。 l sub_match 继承于pair l match_results sub_match的容器,用来表示一次搜索或匹配算法的所有结果,类似于vector 算法: l regex_math 匹配算法,测试一个字符串是否和一个正则式匹配,并通过match_results返回结果。 l regex_find 查找算法,查找字符串的一个和正则式匹配的字串,并通过match_results返回结果。 l regex_format 替换算法,查找字符串中的所有匹配正则式的字串,并使用“格式化字符”串替换。 迭代器: l regex_iterator 枚举一个字符串中所有匹配的字串,regex_iterator的结果相当于match_results. l regex_token_iterator枚举一个字符串中所有匹配的字串,regex_iterator的结果相当于sub_match. 详述 l basic_regex template : allocator classbasic_regex; typedefbasic_regex typedefbasic_regex 很明显,charT是正则式的字符类型,regex和wregex是basic_regex的两个特化。 注意,正则式的字符类型要和需要匹配的字符串的字符类型相同。 例如: 不能在regex_find算法中分别使用string和wregex最为参数,要么是string和regex,要么是wstring和wregex. 构造函数: basic_regexre 产生空的正则式 basic_regexre(str) 正则式为str,str可以为basic_string,也可以是0结尾的char*字符串。 Basic_regexre(re2) 拷贝构造。 basic_regexre(str,flag) 正则式为str,使用flag语法选项,flag是一组常量的组合。 例如: icase可以使正则式匹配忽略大小写。 basic_regexre(beg,end) 使用迭代器构造正则式。 可以是basic_string的迭代器,也可以是constchar*. basic_regexre(beg,end,flag) 使用迭代器构造正则式,flag是语法选项。 常用的语法选项: regex_constants: : normal 默认的语法。 符合EMCAScript,JavaScript中的正则式。 regex_constants: : icase 匹配的时候忽略大小写。 regex_constants: : nosubs 不把匹配的子串保存进match_results结构。 regex_constants: : collate 对于[a-b]的匹配,考虑地区 语法选项通过或运算来结合。 在basic_regex中这些语法选项也进行了定义,所以可以写成regex: : normal,这要比regex_constants少打好几个字母了吧! Jassign成员函数: re.assign(re2) 复制一个正则式 re.assign(str) 正则式为str. re.assign(str,flag) 正则式为str,使用flag语法选项,flag是一组常量的组合。 re.assign(beg,end) 使用迭代器构造正则式。 re.assign(beg,end,flag) 使用迭代器构造正则式,flag是语法选项。 其实basic_regex很多用法和basic_string很像,因为正则表达式也是个字符串嘛! 迭代器: regex: : iteratorit 常迭代器类型,即const_iterator re.begin() 返回的是常迭代器哦! const_iterator re.end() 没有逆向迭代器。 例如: copy(re.begin(),re.end(),ostream_iterator 其他: re.size() 正则表达式长度,即str的长度。 re.max_size() 正则表达式的最大长度。 re.empty() 长度是否为0 re.mark_count() 返回正则式的组数,一般情况下为小括号对数+1.在boost.regex中使用小括号分组,详情请看下面的算法详解。 re.flags() 返回语法选项。 cout< 正则式的流输出,相当于上面示例的copy算法。 swap 成员函数,全局函数都有 re.imbue(loc) 设置local为loc,返回原来的local re.getloc() 得到当前local ==,! =,<,<=,>,>= 比较运算符重载 l sub_match sub_match是一个迭代器组,表示正则式中的一个匹配。 template classsub_match: publicstd: : pair boost没有提供sub_match的任何特化,因为我们不会显示的声明一个sub_match变量。 sub_match是作为match_results的元素用的。 比如: match_results的operator[]和迭代器返回的就是一个特化的sub_match. 唯一的成员变量: boolmatched 是否匹配。 成员函数: length() 返回长度,即两个迭代器之间的距离。 operatorbasic_string 隐式的basic_string转换。 str() 显式的basic_string转换。 还有就是一大堆的比较操作符的重载了,这里就不多说了。 l match_results match_results相当于sub_match的容器,用于表示正则式算法的返回结果。 template classAllocator=allocator classmatch_results; typedefmatch_results typedefmatch_results typedefmatch_results : const_iterator>smatch; typedefmatch_results : const_iterator>wsmatch; 声明很简单,有四个特化可以直接使用,不过要注意string和char*字符串使用的match_results是不同的。 成员函数: m.size() 容量。 m.max_size() 最大容量。 m.empty() 容量是否为0. m[n] 第n个元素,即sub_match m.prefix() 返回代表前缀的sub_match,前缀指字符串的开头到第一个匹配的开头。 m.suffix() 返回代表后缀的sub_match,后缀之最后一个匹配的结尾到字符串的结尾。 m.length(n) 返回第n个元素的长度,即m[n].size()。 m.position(n) 返回第n个元素的位置。 cout< 流输出,输出整个匹配,相当于cout< m.format(fmtstr) 使用格式化字符串,格式化结果,返回字符串 m.format(fmtstr,flags) 使用格式化字符串,格式化结果,返回字符串,flags是格式化选项。 m.format(out,fmtstr) 同上,但是使用输出迭代器输出结果。 m.format(out.fmtstr,flags) 同上,但是使用输出迭代器输出结果。 迭代器: smatch: : iterator 迭代器,常迭代器 smatch: : const_iterator 同上 m.begin() 返回常迭代器 m.end() 同上 最后,说一个实例 我处理一个文本 实际值/-20.031,-1.896,-2.861,-1,0,0 提取其中的数字 regexexp("\s*实际值/(-? [0-9.]+),(-? [0-9.]+),(-? [0-9.]+),(-? [0-9.]+),(-? [0-9.]+),(-? [0-9.]+)$"); 大家看看还有没有更好的写法? regex_match regex_match算法用来测试一个字符串是否完全匹配正则式。 让我们来看一下regex_match的使用: if(regex_match(str,m,re)) { ... } str是一个字符串,可以是string,wstring,char*或者wchar_t* m是match_results,它通过引用传入参数,来保存匹配的结果,m要和str的类型匹配,可以是smatch,wsmatch,cmatch或wcmatch,用来分别对应string,wstring,char*或者wchar_t*的str. re就是正则表达式了,一般来说是regex或wregex. str,m,re的类型如下: 函数的返回值表示字符串是否完全匹配正则表达式,当返回true的时候,m保存了匹配的结果;返回false,m未定义。 下面让我们来看一下,当函数返回true的时候,m是怎么样的。 m.size()==re.mark_count() 还记得re.mark_count()返回的是什么吗? 在上一篇中说的是re.mark_count()返回的时正则式的“组数”,并没有详细解释。 这里我要详细解释一下。 其实,这个“组数”在boost的regex中叫做sub-expression.sub-expression就是在正则式中使用小括号括起来的一部分,正则式本身是一个sub-expression,所以re.mark_count()等于小括号对数+1. m.prefix()和m.suffix() 这两个返回的是sub_match类型(相当于一个迭代器组)。 在regex_match算法中,这两个返回的sub_match都是空的,他们的值如下: (sub_match继承于pair,所以有first和second成员哦) m.prefix()。 first==str.begin() m.prefix()。 second==str.begin() m.prefix()。 matched==false m.suffix()。 first==str.end() m.suffix()。 second==str.end() m.suffix()。 matched==false 因为regex_match是完全匹配,即整个字符串和正则式匹配,所以前缀和后缀都是空的。 m[0] 返回第0个匹配的,由于regex_match是完全匹配,所以 m[0].first==str.begin() m[0].second==str.end() m[0].matched==true m[n],n 返回第n个匹配的sub-expression. m[n].matched表示第n个sub-expression是否在字符串中存在。 整个regex匹配,但是sub_exp可能匹配的是空的,例如“(a*)”就有可以匹配空。 m[n].first和m[n].second表示匹配的范围。 如果匹配空的话,都为str.end()。 根据我的测试,m[1],m[2],……,m[n]的顺序是按照正则式的左小括号的顺序来的,例如对于正则式“((a)bc)d(efg)”,如果匹配了一个字符串的话(字符串只可能是“abcdefg”),则 m[0]==“abcdefg” (sub_match重载了==运算符使得可以和一个字符串比较) m[1]==“abc” m[2]==“a” m[3]==“efg” regex_match的其它
- 配套讲稿:
如PPT文件的首页显示word图标,表示该PPT已包含配套word讲稿。双击word图标可打开word文档。
- 特殊限制:
部分文档作品中含有的国旗、国徽等图片,仅作为作品整体效果示例展示,禁止商用。设计者仅对作品中独创性部分享有著作权。
- 关 键 词:
- C+ 正则表达式 正则 表达式