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-25n"
"2015-09-13n"
"2015 09 13n";
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("[ tn]*[,;.][ tn]*");
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 << "nn";
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);
}
- IronPython资料
- WordPress免插件仅代码实现“返回顶部、返回底部、评论”效果(样式一)
- encodeURIcomponent编码和ASP.NET之间编码转换
- WordPress免插件仅修改代码去掉评论/留言里的链接
- 阅读Ext 学习Javascript(一)Core/Ext.js
- 利用腾讯的ip地址库做ip地址定位
- WordPress登陆不了后台的原因及解决方法(登陆界面不断返回)
- select元素的options.add 与 insertbefore的区别
- 如何去理解 拓扑排序算法
- WordPress免插件仅代码实现文章归档(模板页面)I
- Bing Map App 开发 还没入门遇见错误无法继续
- 使用MongoDB的支持Linq 驱动NoRM
- Ext的组件模型印象
- 2018年预计仍将持续活跃走高的数字货币都有哪些?
- JavaScript 教程
- JavaScript 编辑工具
- JavaScript 与HTML
- JavaScript 与Java
- JavaScript 数据结构
- JavaScript 基本数据类型
- JavaScript 特殊数据类型
- JavaScript 运算符
- JavaScript typeof 运算符
- JavaScript 表达式
- JavaScript 类型转换
- JavaScript 基本语法
- JavaScript 注释
- Javascript 基本处理流程
- Javascript 选择结构
- Javascript if 语句
- Javascript if 语句的嵌套
- Javascript switch 语句
- Javascript 循环结构
- Javascript 循环结构实例
- Javascript 跳转语句
- Javascript 控制语句总结
- Javascript 函数介绍
- Javascript 函数的定义
- Javascript 函数调用
- Javascript 几种特殊的函数
- JavaScript 内置函数简介
- Javascript eval() 函数
- Javascript isFinite() 函数
- Javascript isNaN() 函数
- parseInt() 与 parseFloat()
- escape() 与 unescape()
- Javascript 字符串介绍
- Javascript length属性
- javascript 字符串函数
- Javascript 日期对象简介
- Javascript 日期对象用途
- Date 对象属性和方法
- Javascript 数组是什么
- Javascript 创建数组
- Javascript 数组赋值与取值
- Javascript 数组属性和方法
- 恕我直言你可能真的不会java第9篇-元素的匹配与查找
- 恕我直言你可能真的不会java第8篇-函数式接口
- 突破 DockerHub 限制,全镜像加速服务
- 恕我直言你可能真的不会java第7篇:像使用SQL一样排序集合
- K8S 生态周报| KIND v0.9 发布带来众多更新
- oracle 数据回滚,恢复误删的数据,闪回表功能的使用
- C语言 | 关于结构体内存对齐,看这篇就够了
- Python 图像处理篇-利用opencv库展示本地图片实例演示
- Python 图像处理篇-利用opencv库和numpy库读取包含中文路径下的本地图片实例演示
- 从头创建您自己的vue.js——第2部分(虚拟DOM基础)
- Manage Jenkins报错:"依赖错误: 部分插件由于缺少依赖无法加载...",解决办法
- 从头创建您自己的vuei .js——第3部分(构建VDOM)
- adb 模拟上下左右滑动,示例演示
- python 技术篇-pythoncom.PumpMessag()关闭、杀死它的进程,pythoncom.PumpMessag()运行卡住解决办法
- PyQt5 技术篇-QWidget、QDialog程序窗口关闭closeEvent()触发事件方法重写