Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法…感兴趣就关注我吧!你定不会失望。
0.正则表达式存在必要性
在日常生活,或者刷题过程中我们难免需要检测一段字符是否需要是否符合规定,或在一大段字符中寻找自己想要的信息.
**
一个字一个字来看**十分的费劲且效率低下.有没有一种方法可以快速的匹配到自己需要的文本呢?
假设要判断一个QQ号是否有效,他必须满足以下三个规则
- 长度大于等于5,且小于等于11
- 首位不能是0
- 是否为纯数字
这项工作可以通过c语言来完成
string qq;
cin>>qq;
bool valid=true;
if(qq.legth()<5||qq.length()>11)
valid=false;
if(qq[0]=='0')
valid=false;
for(int i=0;i<qq.length();i++)
{
if(qq[i]<'0'||qq[i]>'9')
valid=false;
}
if(valid)
cout<<"valid"<<endl;
else
cout<<"invalid"<<endl;
虽然看起来很简单就能判断出来了.但这仅是含有数字的QQ号,若我需要判断E-Mail、地址…相信那时的工作绝不是这几行代码就能结束的.
如果使用正则表达式来完成这项工作.代码就会进一步的简介(关于正则表达式的具体语法我们暂且按下不表)
string qq;
cin>>qq;
regex qq_match("[^0][0-9]{4,10}");
bool ret=regex_match(qq,qq_match);
cout<<(ret==true:"valid"?"invalid")<<endl;
仅需五行代码就可以达到上面同等的效果,下面来一起进入正则表达式的世界吧
1.正则表达式介绍
概念就不细说了,仅需要知道:
其叫正则表达式,也叫规则表达式,regex.其核心就是使用特定的文本作为规则,然后去匹配一般的字符串中符合符合这个规则的部分.正则表达式的泛用性很强,在很多高级语言中都有出现.其匹配规则是不变的,改变的仅是使用的函数,
正则表达式的优点很多
- 灵活且逻辑性强
- 可以迅速的以简单的方式达到字符串的控制
缺点就是难,但这应该是我的问题(doge
2.元字符及匹配规则的介绍
^:匹配行的开头:
通常目的是要求正则表达式精确的匹配开头的部分
$:匹配行的结尾:
通常目的是为了精确的匹配到结尾的位置
.:可以匹配除/r与/n以外的任何字符:
r.t 可以匹配到rat也可以匹配到rut
[…]:可以匹配到[]内的任意一个字符
[abcdef]可以匹配到apple
而[ ^abcdef] 则表示可以匹配不在[]范围内的任何字符,plain
[a-z]是范围匹配,可以匹配到小写字母a-z的任意一个
所以[ ^a-z]则表示非小写字母中的任何一个
(…):设定分组
\:转义字符:
所有语言都有的转义字符.也就是\n可能在这个语言中代表的是换行,但是你若就是想匹配其原来的意思,你就可以加上\
此时表示的是匹配\n
\d匹配数字0-9:
相当于[0-9]
\D取反\d:
相当于[ ^0-9]
\w匹配字母数字下划线:
相当于[a-zA-Z0-9_]
\W取反\w:
相当于[ ^a-zA-Z0-9_]
+前面的元素重复一次或多次:
例如zo+可以匹配到"zo" "zooo"但不能匹配到z因为其一次都没出现过
*****前面的任意元素出现了任意次:
例如zo*可以匹配到"zo" “zooo” “z”
**?**前面的元素出现了一次或零次:
例如:thu(er)?可以匹配到thuer,也可以匹配到thu,但不能匹配到thuerer,因为出现了两次
{n}前面的元素出现了n次:
例如"o{2}“可以匹配到"foot” 也可以匹配到"boot,但不能匹配到"Bob"(因为只出现了一次)
{n,}前面的元素出现至少n次:
例如,o{2,}可以匹配到"foooood"但不能匹配到"bob"(因为只出现了一次)
**{n,m}**前面的元素至少出现了n次,最多出现了m次:
例如"o{1,3}"将匹配的"foooooood"前六个o为两组,最后一个o为一组
"o{0,1}等价于(o)?"注意{0,1}之间不能有空格
|逻辑或:
[z|f]ood可以匹配到"food"或者"zood".
以上为较为常见的正则表达式元字符,灵活使用已经可以解决大部分情况
3.C++正则表达式函数:
其包含头文件为
#include<regex>
Regex_match:
常用的匹配函数为其存在标准命名空间里,这里填入需要匹配的表达式
std::regex_match(匹配对象,匹配方式)
例如现在需要匹配一个以下格式的字符串:tel:086-0666-88810009999,利用上面所学知识可以轻松的写出来的他的正则表达式
1{1,3}-[0] [0-9]{2,3}-[0,9]{8,11}$,来解释一下他的含义.
首先从行开头开始:^,前1-3个数字为0-9:[0,9]{1,3},然后出现数字0一位数字0-9二到三个:[0] [0,9]{2,3}
之后再出现八到十一个数字:[0,9]{8,11} 之后就是行结尾:$>
下面是其c++代码示例
#include<iostream>
using namesapce std;
int main()
{
string tel;
cin>>tel;
regex tel_reg("^tel:[0-9]{1,3}-[0][0-9]{2,3}-[0-9]{8,11}$");
bool ret=regex_match(tel,tel_reg);
cout<<(ret?"Valid":"Invalid")<<endl;
}
Regex_repelace
regex_place(匹配对象,匹配方式,替换内容)
下面这段内容为将"he…ll…o, wor…l…d! “中的.全部删掉,也就是替换成”"
#include<iostream>
using namesapce std;
int main()
{
std::string str = "he......ll..o, wor...l...d!";
regex reg("\\.");
cout<<regex_replace(str,reg,"");
}
下面为一些常见的正则表达式匹配文本(可用作理解正则表达式):
验证用户名和密码:"2\w{5,15}$“正确格式:”[A-Z][a-z]_[0-9]"组成,并且第一个字必须为字母,长度6~16位;
验证电话号码:"^(\d{3,4}-)\d{7,8}$"正确格式:xxx/xxxx-xxxxxxx/xxxxxxxx;
验证手机号码(包含虚拟号码和新号码段):“^1([38][0-9]|4[5-9]|5[0-3,5-9]|66|7[0-8]|9[89])[0-9]{8}$”;
验证身份证号(15位):“\d{14}[[0-9],0-9xX]”,(18位):“\d{17}(\d|X|x)”;
验证Email地址:“^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$“或者”[a-zA-z0-9_]+@[a-zA-z0-9]+(.[a-zA-z]+){1,3}”;
只能输入由数字和26个英文字母组成的字符串:“3+$”;
整数或者小数:“4+([.][0-9]+){0,1}$”;
只能输入数字:“5*$”;
只能输入n位的数字:“^\d{n}$”;
只能输入至少n位的数字:“^\d{n,}$”;
只能输入m~n位的数字:“^\d{m,n}$”;
只能输入零和非零开头的数字:“^(0|[1-9][0-9]*)$”;
只能输入有两位小数的正实数:“6+(.[0-9]{2})?$”;
只能输入有1~3位小数的正实数:“7+(.[0-9]{1,3})?$”;
只能输入非零的正整数:“^+?[1-9][0-9]*$”;
只能输入非零的负整数:“^-[1-9][0-9]*$”;
只能输入长度为3的字符:“^.{3}$”;
只能输入由26个英文字母组成的字符串:“8+$”;
只能输入由26个大写英文字母组成的字符串:“9+$”;
只能输入由26个小写英文字母组成的字符串:“10+$”;
验证是否含有^%&',;=? 等 ¨ 字符: " [ \"等字符:"[%&',;=? 等¨字符:"[^“]+”;
只能输入汉字:“11{0,}$”(这里使用了Unicode字符码哦);
验证URL:“^https?😕/([\w-]+.)+[\w-]+(/[\w-./?%&=]*)?$”;
验证一年的12个月:"^(0?[1-9]|1[0-2])$"正确格式为:“01"~"09"和"10"~"12”;
验证一个月的31天:"^((0?[1-9])|((1|2)[0-9])|30|31)$"正确格式为;“01"~"09”、"10"~"29"和“30”~“31”;
获取日期正则表达式:“^\d{4}[年|-|.]\d{\1-\12}[月|-|.]\d{\1-\31}日?$”(可用来匹配大多数年月日信息);
匹配双字节字符(包括汉字在内):“[^\x00-\xff]”(可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1));
匹配空白位置"[\f\n\r\t\v]"(可以用来删除空白行);
匹配HTML标记的正则表达式:“<(\S?)[^>]>.?</>|<.? />”(这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力);
匹配首尾空白字符的正则表达式:"^\s|\s$"(可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式);**
匹配网址URL的正则表达式:“[a-zA-z]+://[^\s]*”;
匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):“12[a-zA-Z0-9_]{4,15}$”;
匹配腾讯QQ号:“[1-9][0-9]{4,10}”;
匹配中国邮政编码:“[1-9]\d{5}(?!\d)”(中国邮政编码为6位数字);
匹配ip地址:“([1-9]{1,3}.){3}[1-9]”(提取ip地址时有用);
匹配MAC地址:(“[A-Fa-f0-9]{2}😃{5}[A-Fa-f0-9]”。
0-9 ↩︎
a-zA-Z ↩︎
A-Za-z0-9 ↩︎
0-9 ↩︎
0-9 ↩︎
0-9 ↩︎
0-9 ↩︎
A-Za-z ↩︎
A-Z ↩︎
a-z ↩︎
\u4e00-\u9fa5 ↩︎
a-zA-Z ↩︎