正则表达式学习(一)
正则表达式是一种十分强大的文本分析工具,其使用了一套复杂的语法规则,解决了文本处理领域的绝大多数问题,诸如验证,匹配,查找以及替换,今天我们就来学习boost库下的xpressive这个先进,灵活的正则表达式库吧,在介绍之前,我们需要了解下正则表达式的一些基础知识: 1)点号开头可以匹配任意的单个字符 2)^匹配行的开头 3)$匹配行的末尾 4)()用于定义一个正则表达式匹配的子元素(子表达式),可以被引用或重复 5)*表示前面的元素可以重复任意多次 6)+表示前面的元素可以重复一次或多次 7)?表示前面的元素可以重复0次或1次 8){}表示手工指定元素重复的次数 9)[]定义字符集合,可以列出单个字符,也可以定义范围或者集合的补集 10)是转义字符,特殊字符转义后与自身匹配 11)|表示逻辑或的概念,匹配它两侧的元素之一 了解了下正则表达式基本规则之后,我们来看看xpressive的一些基础知识,xpressive库提供了两种使用方法:静态和动态,静态的方式类似于spirit,通过使用运算符重载生成编译期的表达式对象,其可以在编译期对语法规则进行检查,而动态的方法主要是在运行期对语法规则进行检查,与boost.regex和python中的re模块很相似,这两种方法不是对立的,在xpressive库中使用较多的主要是动态的方法,因此,我们在此仅就动态的方法进行阐述,首先来看看xpressive库里的几个比较重要的类吧,分别是:basic_regex,match_results和sub_match。 1. basic_regex类 模板类basic_regex时xpressive库的核心类,它封装了正则表达式的解析和编译,下面就来看看basic_regex的类摘要吧,代码如下: template<typename BidiIter> struct basic_regex { basic_regex(); basic_regex(basic_regex<BidiIter>const& s); regex_id_type regex_id()const; std::size_type make_count() const; void swap(basic_regex<BidiIter>&); static basic_regex<BidiIter> compile(InputRange const& p); }; typedef basic_regex<std::string::const_iterator> sregex; typedef basic_regex<char const*> cregex; 在basic_regex类摘要中,regex_id函数返回正则表达式的唯一标志,而make_count函数则返回表达式中匹配的子表达式的个数,compile函数是basic_regex的核心函数,它是一个工厂函数,根据正则表达式参数来创建一个basic_regex对象,其有很多的重载的形式,但是最常用的是一个字符串类型,它必须是一个合法的正则表达式,否则会运行出错 2. match_results类 match_results类也是xpressive库里的一个很重要的类,保存了正则表达式匹配的结果,其类的摘要如下: template<tyname BidiIter> struct match_results { size_type size() const; bool empty() const; template<typename sub> const_refence operator[](sub const& i)const; }; typedef match_results<std::string::const_iterator> smatch; typedef match_results<char const*> cmatch; match_results类为正则表达式匹配结构提供了一个类似容器的视图,使用size函数和empty函数判断匹配结果中子表达式的数量,operator[]返回第i个子表达式。 3. sub_match类 这个模板类是xpressive库中的类似迭代器对的对象,其继承std::pair,可以把它当成字符串区间表示,类摘要如下: template<typename BidiIter> struct sub_match : public std::pair<BidiIter,BidiIter> { string_type str() const; difference_type length() const; bool operator!() const; int compare(string_type const&)const; bool matched; }; 简要的介绍完了xpressive库中的几个重要的类之后,我们就来看看几个简答的测试用例,来熟悉下基本的用法,代码如下: 1. 测试一 #include <boost/xpressive/xpressive_dynamic.hpp> #include <iostream> using namespace boost; using namespace boost::xpressive; using namespace std; int main() { cregex reg = cregex::compile("d{4}"); assert(regex_match("1234",reg)); assert(!regex_match("123d",reg)); assert(!regex_match("adgc",reg)); return 0; } 2. 测试二 #include <boost/xpressive/xpressive_dynamic.hpp> #include <boost/typeof/typeof.hpp> #include <iostream> using namespace boost; using namespace boost::xpressive; using namespace std; int main() { std::string express = "d{6}((1|2)d{3})((0|1)d)([0-3]d)(d{3}(X|d))"; cregex reg = cregex::compile(express,icase); assert(regex_match("999999197002031999",reg)); assert(regex_match("99999919871021999X",reg)); cmatch what; assert(regex_match("99999919900325999x",what,reg)); for(BOOST_AUTO(pos,what.begin());pos != what.end();++pos) { cout<<"["<<*pos<<"]"<<endl; } return 0; } 接下来,我们再来看看几个比较常用的操作,一个regex_search,一个是regex_replace,首先来看看regex_search,其与regex_match最大的区别就是regex_match需要输入的串与正则表达式完全匹配,而regex_search则是检查输入表达式是否包含正则表达式,相比而言,regex_search要比regex_match更灵活,其声明如下: bool regex_search(string,basic_regex const& re); bool regex_search(string,match_result& what,basic_regex const& re); 其实形式与regex_match相同,但是其不要求完全匹配,只要找到有匹配的子串就返回true。实例代码如下: #include <boost/xpressive/xpressive_dynamic.hpp> #include <boost/typeof/typeof.hpp> using namespace boost::xpressive; using namespace boost; using namespace std; int main() { const char* str = "there is a POWER-suit item"; cregex reg = cregex::compile("(POWER)-(.{4})",icase); cmatch what; regex_search(str,reg); for(BOOST_AUTO(pos,what.begin());pos != what.end();pos++) cout<<*pos<<endl; return 0; } 测试结果: POWER-suit 在xpressive库中替换函数regex_replace,其首先通过正则表达式查找匹配,然后使用指定的字符串格式来替换,具体的声明如下: string regex_replace(string,basic_regex const& re,Fomat); 前两个字符串与regex_match类似,第三个参数则是指定了替换的格式,下面就来看看几个简单的测试用例吧,熟悉下regex_replace的用法,代码如下: #include <boost/xpressive/xpressive_dynamic.hpp> #include <iostream> using namespace boost; using namespace boost::xpressive; using namespace std; int main() { string str("zmyer.txt"); sregex reg1 = sregex::compile("(.*)(er)"); sregex reg2 = sregex::compile("(z)(.)(r)"); cout<<regex_replace(str,reg1,"manual")<<endl; cout<<regex_replace(str,"$1you")<<endl; cout<<regex_replace(str,reg2,"$&$&")<<endl; return 0; } 测试结果: manual.txt 总结 本篇博文简要地分析了下boost::xexpressive库,这个库较为精简,并且使用也是很方便的,在实际应用中也偶尔用到,在boost里面还有个更加完整的正则表达式库——regex,本篇只是一个引子,在后续的博文中,我们会有针对性使用正则表达式做一些有意义的东西,好了,本篇博文到此结束,谢谢 如果需要,请注明转载,多谢 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |