突然想写个爬虫,然后发现,如果有正则表达式,会方便些。
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);
}
原文链接: https://www.cnblogs.com/cycxtz/p/4804115.html
欢迎关注
微信关注下方公众号,第一时间获取干货硬货;公众号内回复【pdf】免费获取数百本计算机经典书籍
原创文章受到原创版权保护。转载请注明出处:https://www.ccppcoding.com/archives/221841
非原创文章文中已经注明原地址,如有侵权,联系删除
关注公众号【高性能架构探索】,第一时间获取最新文章
转载文章受原作者版权保护。转载请注明原作者出处!