当前位置:编程学习 > 网站相关 >>

boost xpressive

xpressive:
 正则表达式是处理文本强有力的工具,它使用一套复杂的语法规则,能够解决文本处理领域的绝大多数问题,如验证,匹配,查找,替换等,这些问题用通常的字符串算法是很难甚至无法解决的。
 xpressive是一个先进的,灵活的,功能强大的正则表达式库,提供了对正则表达式的全面支持,而且比原正则表达式库boost.regex要好的是它不需要编译,速度快,同时语法又很类似。

两种使用方式:
 xpressive不仅是一个类似boost.regex的正则表达式解析器,同时它还是一个类似于boost.spirit的语法分析器,并且将这两种完全不相交的文本处理方式完美地融合在了一起。
 因此xpressive提供动态和静态两种使用方式,静态方式类似于spirit,使用操作符重载生成编译期的表达式对象,可以再编译期进行正则表达式的语法检查,动态方式则是较传统的用法,与boost.regex或Python中的re模块很相似,以字符串作为一个表达式对象,在运行时进行语法检查和处理。
 xpressive把这两种方式融合成了一体,两者可以再程序中以任意的形式组合混用。
 【1】如果想混用两种方式或不关心两种方式,可以包含头文件<boost/xpressive/xpressive.hpp>
 【2】如果仅想使用静态方式,可以只包含头文件<boost/xpressive/xpressive_static.hpp>
 【3】如果仅想使用动态方式,可以只包含头文件<boost/xpressive/xpressive_dynamic.hpp>.
本章讨论动态用法:
#include <boost/xpressive/xpressive_dynamic.hpp>
using namespace boost::xpressive;

正则表达式语法简介:
 正则表达式定义了一套完善而复杂的语法规则,用于匹配有特定模式的字符串。在正则表达式中,大部分字符都匹配自己(即普通字符),只有少量的字符被用于定义特殊的匹配模式语法,它们是:.^$()*+?{}[]\|。
 【1】点号(.)可以匹配任意的单个字符,是单字符的通配符.
 【2】^匹配行的开头。
 【3】$匹配行的末尾.
 【4】()用于定义一个正则表达式匹配子元素(子表达式),可以被引用或者重复.
 【5】*表示前面的元素可以重复任意多次(n>=0).
 【6】+表示前面的元素可以重复一次或多次(n>0);
 【7】?表示前面的元素可以重复0次或1次(n = 0,1)。
 【8】{}可以手工指定元素重复的次数。{n}重复x=n次,{n,}重复x>=n次,{n,m}重复n次到m次之间的次数,即n<=x<=m。
 【9】[]用于定义字符集,可以列出单个字符,也可以定义范围,或者是集合的补集。
 【10】\是转义字符(与C/C++)类似,特殊字符经转义后与自身匹配。
 【11】|表示逻辑或的概念,匹配它两侧的元素之一。
示例;
例1:"a."表示字符a和任意一个字符构成的字符串,如ab,a0,但不是abb。
例2:"(a*)(b|c+)"同括号定义了两个子表达式,表示任意数量的a,然后接一个b或者一个以上的c,如:aaab,aaccc,但不是bcc,abccc。
例3"[abc]?.\{\}"表示abc三个字符之一可以出现0次或一次,然后是一个任意字符,在接一个{},如:a={},c2{},但不是ua{},ab。

 正则表达式还使用转义字符斜杠预定义了一些匹配概念,如\d匹配数字相当于([0-9]),\w匹配字母(相当于[a-z]),\s匹配空格等.

 注意:由于c++没有如c#和python那样提供"原始字符串"的表达式,而正则表达式里会经常使用斜杠,在c++代码中就要变成双斜杠,建议在使用正则表达式前可先在普通的文本编辑器里写好,然后用替换功能把所有的单斜杠替换为双斜杠,在代码中使用正则表达式时,一定要在语句前用注释说明其原始表达式,以方便将来的调试和维护。

类摘要:
 xpressive库提供了3个重要的类,分别是:basic_regex,match_results和sub_match。
basic_regex:
 模板类basic_regex是xpressive库的核心,它封装了正则表达式的解析和编译:
template<typename BidiIter>
struct basic_regex
{
 basic_regex();
 basic_regex(basic_regex<BidiIter>const &);

 regex_id_type regex_id() const;
 std::size_t mark_count() const;
 void swap(basic_regex<BidiIter> &);
 
 static basic_regex<BidiIter> compile(InputRange const &pat);
};

typedef basic_regex<std::string::const_iterator> sregex;
typedef basic_regex<char const*> cregex;

 basic_regex是正则表达式的基本类,它常用的是两个typedef:sregex和cregex;sregex用于操作标准字符串类std::string,cregex用于操作字符数组(C风格字符串).
 basic_regex的构造函数,默认构造一个空的正则表达式,支持从另一个basic_regex拷贝构造和赋值,成员函数regex_id()返回正则表达式的唯一标志,mark_count()可以返回表达式中匹配的子表达式的个数,对于空的正则表达式对象,这两个函数都会返回0.
 basic_regex的核心功能是静态成员函数compile(),它是一个工厂方法,可以根据正则表达式参数创建出一个basic_regex对象,compile()有多个重载形式,最常用的是传入一个字符串,否则会运行时发生错误。

match_results:
 match_results是xpressive库里另一个重要类,保存了正则表达式匹配的结果:
template<typename BidiIter>
struct match_results
{
 size_type size() const;
 bool empty() const;
 template<typename Sub> const_reference 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个子表达式,如果i == 0,则返回整个表达式的匹配对象。
 同样,为了支持不同的字符串类型,match_results有两个方便的typedef,分别是smatch和cmatch,用于支持str::string和字符数组,它们命名风格与sregex,cregex是相同的,使用同样的前缀.

sub_match:
 sub_match是一个类似迭代器对的对象,继承自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;
}

匹配:

 自由函数regex_match()用来检查一个字符串是否完全匹配一个正则表达式,返回一个bool结果,有很多重载形式:
 bool regex_match(string, basic_regex const& re);
 bool regex_match(string, match_results& what, basic_regex const &re);
 regex_match()最简单用法是接受两个参数,它的第一个参数是要匹配检查的字符串,第二个参数是正则表达式对象(sregex和cregex).
 regex_match()的第二种重载形式多了个match_results输出参数,可以返回查找到得字串.
示范:
#include <assert.h>
#include <iostream>
#include <boost/xpressive/xpressive_dynamic.hpp>
using namespace boost;
using namespace std;
int main()
{
 using namespace boost::xpressive;
 cregex reg = cregex::compile("a.c"); //c字符串则正表达式对象
 assert(regex_match("abc", reg));
 assert(regex_match("a+c", reg));
 assert(!regex_match("ac", reg));
 assert(!regex_match("abd", reg));
 system("pause");
 return 0;
}

 使用cregex类的工厂方法compile()创建了一个正则表达式对象reg,它可以对字符数组进行正则表达式匹配。
 
示例:匹配身份证号码
 身份证的基本编码规则,它是由18位数字组成的,前6位是地区编码,中间8位是年月日,最后4位数字可能有一个x。
 使用\d来表示数字,那么前6位的正则表达式是\d{6},后4位的正则表达式是:\d{3}(X|\d)。中间的年月日的检验要稍微复杂一些,不检查闰年和月份天数的有效性,可以写成:(1|2)\d{3}(0|1)\d[0-3]\d。其中的(1|2)\d{3}检查4位的年份,第一个数字必须是1或2,(0|1)\d检查月份,[0-3]\d检查天.
 把这些组合起来得到:\d{6}(1|2)\d{3}(0|1)\d[0-3]\d\d{3}(X|\d),在转换成C字符串就是:"\\d{6}(1|2)\\d{3}(0|1)\\d[0-3]\\d\\d{3}(X|\\d)"
示范:
#include <assert.h>
#include <iostream>
#include <boost/xpressive/xpressive_dynamic.hpp>
using namespace boost;
using namespace std;
int main()
{
 using namespace boost::xpressive;
 //c字符串则正表达式对象, 最后参数icase用于指示匹配时忽略大小写
 cregex reg = cregex::compile(&quo

补充:综合编程 , 其他综合 ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,