加入收藏 | 设为首页 | 会员中心 | 我要投稿 李大同 (https://www.lidatong.com.cn/)- 科技、建站、经验、云计算、5G、大数据,站长网!
当前位置: 首页 > 百科 > 正文

正则表达式学习(一)

发布时间:2020-12-13 23:10:44 所属栏目:百科 来源:网络整理
导读:正则表达式是一种十分强大的文本分析工具,其使用了一套复杂的语法规则,解决了文本处理领域的绝大多数问题,诸如验证,匹配,查找以及替换,今天我们就来学习boost库下的xpressive这个先进,灵活的正则表达式库吧,在介绍之前,我们需要了解下正则表达式的

正则表达式是一种十分强大的文本分析工具,其使用了一套复杂的语法规则,解决了文本处理领域的绝大多数问题,诸如验证,匹配,查找以及替换,今天我们就来学习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
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
zmyyou.txt
zmyer.txt

总结

本篇博文简要地分析了下boost::xexpressive库,这个库较为精简,并且使用也是很方便的,在实际应用中也偶尔用到,在boost里面还有个更加完整的正则表达式库——regex,本篇只是一个引子,在后续的博文中,我们会有针对性使用正则表达式做一些有意义的东西,好了,本篇博文到此结束,谢谢

如果需要,请注明转载,多谢

(编辑:李大同)

【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容!

    推荐文章
      热点阅读