优势: 使得字符串的处理更加简单
一些相关的操作:
验证:检查字符串是否是想要的合法性
决策:判断一个输入标书哪种字符串
解析:从输入的字符串中查找自己想要的信息
转换:搜索字符串,并将字符串替换为新的格式化的字符串
遍历:搜索字符串所有出现的地方
符号化:根据一组分隔符将一个字符串分解为多个子字符串
一些重要术语:
模式:正则表达式实际上和给定序列中所有字符是否匹配
匹配:判断正则表达式和给定的序列[first,last)中所有字符是否匹配
搜索:判断在给定的序列[first,last]中是否存在匹配给定正则表达式的子字符串
替换:在给定的序列中识别子字符串,然后将子字符串替换为从其他模式计算得到的新子字符串
现在讲一些C++11标准中如何使用正则表达式
1.正则表达式模式是一个字符序列(说透了底层还不是利用简单的C++语法进行字符的切割
分离等等的操作只不过普通人写的没那么好没那么健壮)
这个模式表示了要匹配的内容,正则表达式中任何字符都表示要匹配自己,但是有些字符
除外 例如:^$ \ . * + ? () {} | 等
注意:在C++中转义反斜杠 例如 对于需要利用正则表达式匹配单个的*字符
需要这样写\\*。
1)^和 $
^字符匹配字符串的开头位置 $字符匹配字符串的结尾位置
例如:^test$ 只能匹配test 不能匹配其他
2)通配符.
通配符字符可以匹配除了换行以外的所有字符
例如:a.b 可以匹配acbabb ayb a0b等等(中间只有一个字符)
3)重复
*匹配零次或者多次之前的部分
例如:a*b 可以匹配b,ab,aab,aaa,aaaa...b;
+匹配一次多着多次之前的部分
例如:(上一个看懂就不举例了)
?匹配零次或者一次之前的部分
{...}表示区间重复
a{n}表示重复匹配an次
a{n,}表示重复匹配an次或者更多次
a{n,m} 表示重复匹配an到m之间的那么多次包含m,n
4)替代
例如 a|b 表示匹配a或者b
5)字符集匹配
[a1a2a3] 表示可以匹配a1,a2,a3中任意字符
例如:ab[cde] 表示可以匹配abcabd abe
如果要匹配26个字母中之一呢 不会[a|b|c|d....]这样吧
于是字符类出现了
alnum:小写字母 大写字母和数字
alpha:小写字母和大写字母
blank:空格或者制表符
cntrl:文件格式转义字符 例如换行符 和 回车符(\f\n \r \t)
digit:数字
graph:小写字母 大写字母 数字和标点符号
lower:小写字母
print:小写字母 大写字母 数字标点符号和空白字符
punch:标点符号字符
space:空白字符
upper:大写字母
xdigit:数字和'a','b','c','d','e','f'。'A','B','C','D','E','F'
d:数字
s:空白字符
w:小写字母 大写字母和数字
先就这几种比较简单的 呵呵
现在可以使用代码案例了:
我们使用正则表达式来看看一个时间的输入是否正确
regexre("^(\\d{4})/(?:0?[1-9]|1[0-2])/(?:0?[0-9]|[1-2][0-9]|3[0-1])$");
*表示正则的形式我们首先来分析下 ^表示开始 最后的$表示结束
*\\d{4} 表示是一个4位的数字/表示/用来分隔时间(所以输入的时候要注意)
*月份的表示形式(0?[1-9]|1[0-2])1-9月份 1011 22
*后面的日期和月份一样来分析(包括对时间的检测)
#include<iostream>
#include<regex>
usingnamespace std;
boolisTrue(int year,int month,int day) //进行时间的验证
{
if(year<0|| year>9999)
returnfalse;
if(month<=0|| month >12)
returnfalse;
if(day<0 || day>31)
returnfalse;
intdays = 0;
switch(month)
{
case1:
days= 31;
break;
case2:
if((year%4==0&&year%100!=0)||(year%100==0&&year%400==0))
days= 28;
else
days= 29;
break;
case3: case 5: case 7: case 8: case 10: case 12:
days= 31;
break;
case4: case 6: case 9: case 11:
days= 30;
break;
}
if(day> days) //在相应的月份比较过后
returnfalse; //进行时间的断定
returntrue;
}
intmain()
{
regexre("^(d{4})/(?:0?[1-9]|1[0-2])/(?:0?[0-9]|[1-2][0-9]|3[0-1])$");
while(true)
{
cout<<"pleaseenter a time:";
stringsTime;
cin>>sTime;
if(sTime=="quit")
break;
smatchmTime;
if(regex_match(sTime,mTime,re))
{
cout<<"你的输入是正确的!"<<endl;
intyear = atoi(mTime[1].str().c_str());
intmonth = atoi(mTime[2].str().c_str());
intday = atoi(mTime[3].str().c_str());
if(isTrue(year,month,day) == true)
cout<<"year:month:day"<<year<<month<<day<<endl;//这里智能够打印年份(在VS2013上测试的)
}
else
cout<<"你的输入不正确!"<<endl;
}
return0;
}
进行字符串的读取
#include<iostream>
#include<regex>
usingnamespace std;
intmain()
{
regexre("[\\w]+"); //表示要搜索一个或者多个单词
while(true)
{
cout<<"pleaseenter a string:"<<endl;
stringstr;
cin>>str;
if(str=="quit")
break;
constsregex_iterator end;
for(sregex_iteratorit(str.begin(),str.end(),re); it!=end; ++it)
cout<<"\t"<<(*it)[0]<<"\"<<endl;
//sregex_iteratorvs对他的支持好像也比较弱此处智能打印头个字符串
}
}
#include<iostream>
#include<regex>
usingnamespace std;
intmain()
{
regexre("//\\s*(.+)");
while(true)
{
cout<<"Entera string"<<endl;
stringstr;
cin>>str;
if(str== "quit")
break;
smatchsStr;
if(regex_search(str,sStr,re))
cout<<"["<<sStr[0]<<"]";//主要是打印第一个字符串
else
cout<<"Nofound!"<<endl;
}
}
/
//现在进行字符串的替换
regex_replace
#include<iostream>
#include<regex>
usingnamespace std;
intmain()
{
//进行替换
stringstr("<body>This is a test from jack_li'sprogramming!</body>");
regexre("<body>(.*)</body>");
stringformat("body=$1");
stringresult = regex_replace(str,re,format);
cout<<result<<endl;
}
//替换这个函数的支持还不错结果也很正确
//这个网站介绍了一些正则表达式:
http://www.360doc.com/content/10/1216/11/1232501_78611865.shtml
最后,感觉VS编译器和CodeBlock对正则的支持还不是那样理想正则很强大 这里先介绍一部分。满足下我的求知欲(呵呵)