C++ boost正则表达式用法
当前位置:以往代写 > C/C++ 教程 >C++ boost正则表达式用法
2019-06-13

C++ boost正则表达式用法

C++ boost正则表达式用法

副标题#e#

什么是正则表达式?正则表达式是一种用来描写必然数量文本的模式。Regex代表Regular Express.

假如您不知道什么是正则表达式,请看这篇文章:深入浅出之正则表达式

有了正则表达式的基本,问题是如何利用。我们以boost::regex来说

先看一个网上经典的例子。

 #include "stdafx.h"

#include <cstdlib>

#include <stdlib.h>

#include <boost/regex.hpp>

#include <string>

#include <iostream>

using namespace std;

using namespace boost;

regex expression("^select ([a-zA-Z]*) from ([a-zA-Z]*)");

int main(int argc, char* argv[])

{

 std::string in;

 cmatch what;

 cout << "enter test string" << endl;

 getline(cin,in);

 if(regex_match(in.c_str(), what, expression))

 {

for(int i=0;i<what.size();i++)

 cout<<"str :"<<what[i].str()<<endl;

 }

 else

 {

cout<<"Error Input"<<endl;

 }

 return 0;

}

功效

输入:select name from table

输出:str:select name from table

str:name

str:table

凭据我们的要求,字符串被匹配挑出来了。

这在处理惩罚大量法则的文本名目标时候很有用,因为它很机动,一通百通。

首先,纵然你拥有了boost库,也需要单独编译regex.

网上的先容:

boost库安装较量贫苦,需要本身编译源文件,我整理了一下,假如仅仅需要做正则表达式,按下面的代码敲就行了:

cmd

vcvars32.bat

cd D:\boost_1_32_0\libs\regex\build

d:

nmake -fvc6.mak

nmake -fvc6.mak install

留意,别看下载下来的数据包没有多大,解压缩之后到达了100多M,编译完之后为109M,占用131M,所以安装时必然留意空出足够的空间,敲入nmake -fvc6.mak后期待的时间较量长,屏幕上还会呈现一大堆英语,可以不做思量。凭据步调往下敲就行了。压缩包内文档很具体,参照文档继承就可以了。

在VC6中集成:Tools->Options->Directories->Include files

插手:D:\boost_1_32_0

我用的是VS2003做了run.bat

chdir E:\Program\boost_1_34_1
bjam "-sTOOLS=vc-7_1" "-sVC71_ROOT=D:\Program Files\Microsoft Visual Studio .NET 2003\Vc7" "--prefix=E:\Program\boost" "--builddir=E:\Program\boost_1_34_1\build" "-sBUILD=debug release <runtime-link>static/dynamic" --with-regex install
PAUSE

至于参数,需要参考boost安装先容http://blog.csdn.net/begtostudy/archive/2007/11/11/1879213.aspx


#p#副标题#e#

其他的一些先容

 bool validate_card_format(const std::string s)
        {
           static const boost::regex e("(\\d{4}[- ]){3}\\d{4}");
           return regex_match(s, e);
        }

boost::regex的默认正则表达式语法是perl语法

boost::regex支持perl regular表达式、POSIX-Extended regular表达式和POSIX-Basic Regular表达式,但默认的表达式语法是perl语法,假如要利用其余两种语法需要在结构表达式的时候明晰指定。

譬喻,下面两种要领结果沟通

  // e1 is a case sensitive Perl regular expression:
        // since Perl is the default option there''s no need to explicitly specify the syntax used here:
        boost::regex e1(my_expression);
        // e2 a case insensitive Perl regular expression:
        boost::regex e2(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次以上(含)

{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编码的支持

#p#分页标题#e#

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::regex e2(my_expression, boost::regex::perl|boost::regex::icase);

模板类:

l         basic_regex          用来生存一个“正则表达式”的类。

l         sub_match            担任于pair<Iterator,Iterator>迭代器组,用来暗示匹配的一个功效。

l         match_results             sub_match的容器,用来暗示一次搜索或匹配算法的所有功效,雷同于vector<sub_match>.

算法:

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.

#p#副标题#e#

详述

l       basic_regex

template <class charT, class traits = regex_traits<charT>, class Allocator = std::allocator<charT>  >

class basic_regex;

typedef basic_regex<char> regex;

typedef basic_regex<wchar_t> wregex;

很明明,charT是正则式的字符范例,regex和wregex是basic_regex的两个特化。

留意,正则式的字符范例要和需要匹配的字符串的字符范例沟通。譬喻:不能在regex_find算法中别离利用string和wregex最为参数,要么是string和regex,要么是wstring和wregex.

结构函数:

basic_regex re

发生空的正则式

basic_regex re(str)

正则式为str,str可觉得basic_string,也可以是0末了的char*字符串。

Basic_regex re(re2)

拷贝结构。

basic_regex re(str,flag)

正则式为str,利用flag语法选项,flag是一组常量的组合。譬喻:icase可以使正则式匹配忽略巨细写。

basic_regex re(beg,end)

利用迭代器结构正则式。可以是basic_string的迭代器,也可以是const char*.

basic_regex re(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少打好几个字母了吧!J assign成员函数:

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::iterator it

常迭代器范例,即const_iterator

re.begin()

返回的是常迭代器哦!const_iterator

re.end()

没有逆向迭代器。

譬喻:copy(re.begin(), re.end(), ostream_iterator<char>(cout));

#p#副标题#e#

其他:

re.size()

正则表达式长度,即str的长度。

re.max_size()

正则表达式的最大长度。

re.empty()

长度是否为0

re.mark_count()

返回正则式的组数,一般环境下为小括号对数+1.在boost.regex中利用小括号分组,详情请看下面的算法详解。

re.flags()

返回语法选项。

cout<<re

正则式的流输出,相当于上面示例的copy算法。

swap

成员函数,全局函数都有

re.imbue(loc)

配置local为loc,返回本来的local

re.getloc()

获得当前local

==,!=,<,<=,>,>=

较量运算符重载

l       sub_match

sub_match是一个迭代器组,暗示正则式中的一个匹配。

template <class BidirectionalIterator>

class sub_match : public std::pair<BidirectionalIterator, BidirectionalIterator>;

#p#分页标题#e#

boost没有提供sub_match的任何特化,因为我们不会显示的声明一个sub_match变量。sub_match是作为match_results的元素用的。好比:match_results的operator[]和迭代器返回的就是一个特化的sub_match.

独一的成员变量:

bool matched  是否匹配。

成员函数:

length()

返回长度,即两个迭代器之间的间隔。

operator basic_string< value_type>()

隐式的basic_string转换。

str()

显式的basic_string转换。

尚有就是一大堆的较量操纵符的重载了,这里就不多说了。

l       match_results

match_results相当于sub_match的容器,用于暗示正则式算法的返回功效。

 template <class BidirectionalIterator,

          class Allocator = allocator<sub_match<BidirectionalIterator> >

class match_results;

 

typedef match_results<const char*> cmatch;

typedef match_results<const wchar_t*> wcmatch;

typedef match_results<string::const_iterator> smatch;

typedef match_results<wstring::const_iterator> wsmatch;

#p#副标题#e#

声明很简朴,有四个特化可以直接利用,不外要留意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<<m

流输出,输出整个匹配,相当于cout<<m[0].因为第0个元素是整个匹配,具体环境请看下面的表明。

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

提取个中的数字

regex exp("\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))

{

    ...

}

#p#副标题#e#

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的范譬喻下:

C++ boost正则表达式用法

函数的返回值暗示字符串是否完全匹配正则表达式,当返回true的时候,m生存了匹配的功效;返回false,m未界说。

下面让我们来看一下,当函数返回true的时候,m是怎么样的。

m.size() == re.mark_count()

#p#分页标题#e#

还记得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<m.size()

返回第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的其它用法

C++ boost正则表达式用法

regex_search

regex_search的用法根基上和regex_match一样。

 if (regex_search(str, m, re))

{

    ...

}

regex_search不要求str完全匹配re,只要str中的一个字串匹配re就可以了。所以,m.prefix()和m.suffix()不必然为空。

regex_search是从左往右匹配,并且只管匹配长的字串。

    关键字:

在线提交作业