C++11正则表达式 ECMAScript文法

突然想写个爬虫,然后发现,如果有正则表达式,会方便些。

C++11提供了Regex类.可以用来完成:

1.Match: 将整个输入拿来比对(匹配)某个正则表达式。

2.Search:查找“与正则表达式吻合”的子序列。

3.Tokenize:正则表达式作为分割器,得到分割器之前的字符串。

4.Replace:将与正则表达式吻合之的子序列替换掉

主要函数有: regex_match(),regex_search(),regex_replace();

主要对象:sregex_iterator,sregex_token_iterator,regex,smatch

例子:

[_[:alpha:]][_[:alnum:]]* 表示,以_或字母开头,后面接着任意个_或字母的组合

[123]?[0-9]\.1?[0-9]\.20[0-9]{2} 表示german format,如 24.12.2010

C++11默认使用 ECMAScript 文法,告诉你怎么构造正则表达式

表示式 意义
. newline以外的任何字符
[...] ...字符中的任何一个
[^...] ...字符之外的任何一个
[ [:charclass:]] 指定字符串类charclass中的一个(见下表)
\n,\t,\f,\r,\v 一个newline,tabulator,form feed,carriage return,vertical tab
\xhh,\uhhh 一个十六进制字符或Unicode字符
* 前一个字符或群组,任意次数
? 前一个字符或群组,可有可无
+ 前一个字符或群组,至少一次
{n} 前一个字符或群组,n次
{n,} 前一个字符或群组,至少n次
{n,m} 前一个字符或群组,至少n次,至多m次
...|... 在 | 之前或之后的pattern,合并左边和右边,(.|\n)*表示任意字符和任意换行
(...) 设定群组(group)
\1,\2,\3 第n个group(第一个group的索引为1)
\b 一个正字词边界,字词的起点或终点,不知道什么意思
\B 一个负字词的边界,字词的非起点或非终点
^ 一行的起点
$ 一行的终点
字符类 缩写 转义 效果
[[:alnum:]]     一个字母或者数字
[[:alpha:]]     一个字母
[[:blank:]]     一个space或者tab
[[:cntrl:]]     一个控制字符
[[:digit:]] [[:d:]] \d 一个数字
    \D 一个非数字
[[:graph:]]     可打印非空白字符,相当于[[:alnum:][:punct:]]
[[:lower:]]     一个小写字母
[[:print:]]     一个可打印字符,包括空白字符
[[:punct:]]     一个标点符号字符,但非space,digit,letter
[[:space:]]   \s 一个空白字符
    \S 一个非空白字符
[[:upper:]]     一个大写字母
[[:xdigit:]]     一个十六进制数字
    \w 一个字母、数字或下划线
    \W 一个非字母、非数字

附上一个测试例子:

#include <regex>
#include <iostream>
#include <string>
#include <iomanip>
#include <algorithm>

using namespace std;

void out(bool b){
    cout << ( b? "found" : "not found") << endl;
}

void regex1();
void regex2();
void regex3();
void regex4();
void regex5();
void regex6();

int main(){
    //regex1();
    //regex2();
    //regex3();
    //regex4();
    //regex5();
    //regex6();

    string data = "1994-06-25\n"
                  "2015-09-13\n"
                  "2015 09 13\n";
    smatch m;
    regex reg("(\\d{4})[- ](\\d{2})[- ](\\d{2})");
    //sregex_iterator pos(data.cbegin(),data.cend(),regex("(\\d{4})[- ](\\d{2})[- ](\\d{2})"));
    sregex_iterator pos(data.cbegin(),data.cend(),reg);
    sregex_iterator end;
        for( ; pos!=end ;pos++){
            cout << pos->str() << " ";
            cout << pos->str(1) << " " <<pos->str(2) <<" " << pos->str(3) << endl;
        }

    system("pause");
    return 0;
}

/*
 * regex_replace(string,reg1,reg2)
 * 将reg1匹配到的子串,用reg2替换掉
 */
void regex6(){
    string data = "<person>\n"
        "<first>Nico</first>\n"
        "<last>Josuttis</last>\n"
        "</person>\n";
    regex reg("<(.*)>(.*)</(\\1)>");

    cout << regex_replace(data,reg,"<$1 value=\"$2\"/>") << endl;

    string res2;

    regex_replace (back_inserter(res2),
                   data.begin(),data.end(),
                   reg,
                   "<$1 value=\"$2\"/>",
                   regex_constants::format_no_copy
                   | regex_constants::format_first_only);
    cout << res2 << endl;
}

/*
 * sregex_token_iteartor 分割器
 * 详情看函数输出,比如,通过这个,可以取出下面的名字
 */
void regex5(){
    string data = "<person>\n"
        "<first>Nico</first>\n"
        "<last>Josuttis</last>\n"
        "</person>\n";
    regex reg("<(.*)>(.*)</(\\1)>");

    sregex_token_iterator pos(data.cbegin(),data.cend(),reg,0);
    sregex_token_iterator end;

    for(; pos!=end;pos++){
        cout << "match:    "<<pos->str() << endl;
    }
    cout<< endl;

    string names = "nico,jim,helmut,paul,tim,john paul,rita";
    regex sep("[ \t\n]*[,;.][ \t\n]*");
    sregex_token_iterator p(names.cbegin(),names.cend(),sep,-1);
    sregex_token_iterator e;
    for(; p!=e;p++){
        cout << "name:    "<<*p << endl;
    }
}

/*
 * sregex_iterator 迭代器,通过这样个来遍历所以满足的子串
 * 注意传进去的 begin,end 必须是const 所以使用 cbegin()
 */
void regex4(){
    string data = "<person>\n"
        "<first>Nico</first>\n"
        "<last>Josuttis</last>\n"
        "</person>\n";
    regex reg("<(.*)>(.*)</(\\1)>");

    sregex_iterator pos(data.cbegin(),data.cend(),reg);
    sregex_iterator end;
    for(;pos != end;++pos){
        cout << "match:    "<< pos->str(0) << endl;
        cout << "tag:    "<< pos->str(1)<< endl;
        cout << "value    "<< pos->str(2) << endl;
    }

    sregex_iterator beg(data.cbegin(),data.cend(),reg);
    for_each(beg,end,[](const smatch& m){
        cout << "match:    "<< m.str() << endl;
        cout << "tag:    "<< m.str(1)<< endl;
        cout << "value    "<< m.str(2) << endl;
    });
}

/*
 *  bool regex_search(string , smatch ,regex )
 *  对整个字符串,用这个regex进行匹配,找到第一个满足的子串,
 *  通过前面的例子,可以发现 m.suffix() 指得是,满足子串后面的,
 *  一个字符的索引,所以,通过一个循环,可以不断找出后面满足的
 */
void regex3(){
    string data = "<person>\n"
        "<first>Nico</first>\n"
        "<last>Josuttis</last>\n"
        "</person>\n";
    regex reg("<(.*)>(.*)</(\\1)>");

    auto pos = data.cbegin();
    auto end = data.cend();

    smatch m;

    for(; regex_search(pos,end,m,reg);pos = m.suffix().first){
        cout << "match:        "<<m.str() << endl;
        cout << "tag:        "<<m.str(1) << endl;
        cout << "value:  " << m.str(2) << endl;
        cout << "m.prefix():    "<<m.prefix().str() << endl;
        cout << "m.suffix():    "<<m.suffix().str() << endl;
    }
}

/*
 *  bool regex_search(string , smatch ,regex )
 *  对整个字符串,用这个regex进行匹配,找到第一个满足的子串,
 *  下面是通过smatch 获取子串内容的方法,索印对应群组
 */
void regex2(){
    string data = "XML tag: <tag-name>the value</tag-name>.";
    cout << "data:        "<<data << "\n\n";

    smatch m;
    bool found = regex_search(data,m,regex("<(.*)>(.*)</(\\1)>"));

    cout << "m.empty():        "<<boolalpha << m.empty() << endl;
    cout << "m.size():        "<<m.size() << endl;
    if(found){
        cout << "m.str():        "<<m.str() << endl;
        cout << "m.length():        "<<m.length()<<endl;
        cout << "m.position():        "<<m.position()<<endl;
        cout << "m.prefix().str():  "<<m.prefix().str()<< endl;
        cout << "m.suffix().str():  "<<m.suffix().str() << endl;
        cout << endl;

        for(int i = 0;i<m.size();i++){
            cout << "m["<<i<<"].str():        " << m[i].str() << endl;
            cout << "m.str("<<i << "):        " << m.str(i) << endl;
            cout << "m.position(" << i << "):        "<<m.position(i)<<endl;
        }
        cout << endl;

        cout << "matches:" << endl;
        for(auto pos = m.begin();pos!=m.end();pos++){
            cout << " "<< *pos << " ";
            cout << "(length:  " << pos->length() << ")" << endl;
        }
    }
}

/*
 *  bool regex_match(string , regex )
 *  对整个字符串,用这个regex进行匹配,会匹配最大满足的字符串
 */
void regex1(){
    regex reg1("<.*>.*</.*>");
    bool found = regex_match("<tag>value</tag>",reg1);
    out(found);

    regex reg2("<(.*)>.*</\\1>");
    found = regex_match("<tag>value</tag>",reg2);
    out(found);

    regex reg3("<\\(.*\\)>.*</\\1>",regex_constants::grep);
    found = regex_match("<tag>value</tag>",reg3);
    out(found);

    found = regex_match("<tag>value</tag>",regex("<(.*)>.*</\\1>"));
    out(found);

    cout << endl;

    found = regex_match("XML tag: <tag>value</tag>",
        regex("<(.*)>.*</\\1>"));
    out(found);

    found = regex_match("XML tag: <tag>value</tag>",
        regex(".*<(.*)>.*</\\1>"));
    out(found);

    found = regex_search("XML tag: <tag>value</tag>",
        regex("<(.*)>.*</\\1>"));
    out(found);

    found = regex_search("XML tag: <tag>value</tag>",
        regex(".*<(.*)>.*</\\1>"));
    out(found);
}
时间: 2024-10-28 11:33:41

C++11正则表达式 ECMAScript文法的相关文章

C++11 正则表达式库 (regex)

Source: http://cpprocks.com/wp-content/uploads/c++11-regex-cheatsheet.pdf C++11 正则表达式库 (regex),布布扣,bubuko.com

cocos2dx下C++11正则表达式和android下C语言正则表达式的使用--------案例密码校验

/************************************************************************/ /* 密码校验 */ /* C++11下没有问题,但是C语言是有问题的 */ /* 错误案例:^[[email protected]#$%^&*()_+`\\-={}\\[\\]:\";'<>?,.\\/]{6,20}$ 正确案例:^[][email protected]#$%^&*()_+`={}:;'<>

1.11正则表达式基础(学习过程)

正则表达式基础 实验介绍 虽然我们这一节的标题是正则表达式,但实际这一节实验只是介绍grep,sed,awk这三个命令,而正则表达式作为这三个命令的一种使用方式(命令输出中可以包含正则表达式).正则表达式本身的内容很多,要把它说明清楚需要单独一门课程来实现,不过我们这一节中涉及到的相关内容通常也能够满足很多情况下的需求了. 想要更深入地学习使用正则表达式,在这里 正则表达式基础. 一.正则表达式 什么是正则表达式呢? 正则表达式,又称正规表示式.正规表示法.正规表达式.规则表达式.常规表示法(英

C++11 正则表达式简单运用

正则表达式(regular expression)是计算机科学中的一个概念,又称规则表达式,通常简写为regex.regexp.RE.regexps.regexes.regexen. 正则表达式是一种文本模式.正则表达式是强大.便捷.高效的文本处理工具.正则表达式本身,加上如同一门袖珍编程语言的通用模式表示法(general pattern notation),赋予使用者描述和分析文本的能力.配合上特定工具提供的额外支持,正则表达式能够添加.删除.分离.叠加.插入和修整各种类型的文本和数据. 完

C++11正则表达式初探

C++正则表达式 在此之前都没有了解过C++的正则,不过现在大多数赛事都支持C++11了,因此有必要学习一下,用于快速A签到题. 所在头文件 #include<regex> 正则表达式语法 跟其他语言的正则语法基本一样,要注意的是转义需要两个\\,如匹配数字的\d应该写成\\d: regex使用语法 regex pattern("正则表达式");//匹配规则 smatch result;//用于存放匹配结果 string s;//待匹配的文本串 库里有三个函数供我们使用,下

Day 11 正则表达式

正则表达式 一.简介 Linux系统中grep命令是一种强大的文本搜索工具,它能使用正则表达式搜索文本,并把匹配到的行打印出来.grep全称是Globally search for a Regular Expression and  print  out the line,表示全局搜索正则表达式并打印匹配结果的意思.Linux下所有用户都可以使用. 二.格式 grep [option] "pattern" FILE 三.常用选项

黑马程序员——11 正则表达式

------Java培训.Android培训.iOS培训..Net培训.期待与您交流! ------- 正则表达式 一.概念 符合一定规则的表达式,用于专门操作字符串,可以简化对字符串的复杂操作,主要用于一些特定的符号来表示一些代码操作. 二.常见符号 2.1字符 x                  字符 x \\                 反斜线字符 \t                 制表符 ('\u0009') \n                 新行(换行)符 ('\u000

lesson - 11 正则表达式

正则就是有一定规律的字符串,有几个特殊符号很关键(. * + ? | ),我们平时不仅可以用命令行工具grep/sed/awk去引用正则,而且还可以把正则嵌入在nginx.apache.甚至php.python编程语言当中,学好正则可以让你受用无穷!一.grep/egrep 1. 语法+选项语法: grep  [-cinvABC]  'word'  filename -c :打印符合要求的行数-n :在输出符合要求的行的同时连同行号一起输出 -v :打印不符合要求的行 -A :后跟一个数字(有无

查看,统计、正则表达式——Linux基本命令(9)

1.文件查看 (1)正向查看 cat cat -v 显示非打印字符 -E 显示$ -T 显示TAB -n 显示行号(与nl作用类似) -s 将连续的重复的空行变成一行(与tr -s作用类似,将多个重复的变成一个,如图将多个换行符变成了一个) -A = -vET都显示 (2)整个文件反向查看 tac 反向输出 将文件倒过来输出 (3)一行反向查看 rev 将每一行反向输出 2.分页查看文件内容 more: 分页查看文件 more [OPTIONS...] FILE... -d: 显示翻页及退出提示