【C++技能树】快速文本匹配 --正则表达式介绍与C++正则表达式使用

简介: 假设要判断一个QQ号是否有效,他必须满足以下三个规则

Halo,这里是Ppeua。平时主要更新C语言,C++,数据结构算法…感兴趣就关注我吧!你定不会失望。


36603d2e4ee04064a06d32db1bfdf360.png


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.其核心就是使用特定的文本作为规则,然后去匹配一般的字符串中符合符合这个规则的部分.正则表达式的泛用性很强,在很多高级语言中都有出现.其匹配规则是不变的,改变的仅是使用的函数,


正则表达式的优点很多


1.灵活且逻辑性强

2.可以迅速的以简单的方式达到字符串的控制


缺点就是难,但这应该是我的问题(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,"");
}


下面为一些常见的正则表达式匹配文本(可用作理解正则表达式):


1.验证用户名和密码:"2\w{5,15}$“正确格式:”[A-Z][a-z]_[0-9]"组成,并且第一个字必须为字母,长度6~16位;


2.验证电话号码:"^(\d{3,4}-)\d{7,8}$"正确格式:xxx/xxxx-xxxxxxx/xxxxxxxx;


3.验证手机号码(包含虚拟号码和新号码段):“^1([38][0-9]|4[5-9]|5[0-3,5-9]|66|7[0-8]|9[89])[0-9]{8}$”;


4.验证身份证号(15位):“\d{14}[[0-9],0-9xX]”,(18位):“\d{17}(\d|X|x)”;


5.验证Email地址:“^\w+([-+.]\w+)@\w+([-.]\w+).\w+([-.]\w+)*$“或者”[a-zA-z0-9_]+@[a-zA-z0-9]+(.[a-zA-z]+){1,3}”;


6.只能输入由数字和26个英文字母组成的字符串:“3+$”;


7.整数或者小数:“4+([.][0-9]+){0,1}$”;


8.只能输入数字:“5*$”;


9.只能输入n位的数字:“^\d{n}$”;


10.只能输入至少n位的数字:“^\d{n,}$”;


11.只能输入m~n位的数字:“^\d{m,n}$”;


12.只能输入零和非零开头的数字:“^(0|[1-9][0-9]*)$”;


13.只能输入有两位小数的正实数:“6+(.[0-9]{2})?$”;


14.只能输入有1~3位小数的正实数:“7+(.[0-9]{1,3})?$”;


15.只能输入非零的正整数:“^+?[1-9][0-9]*$”;


16.只能输入非零的负整数:“^-[1-9][0-9]*$”;


17.只能输入长度为3的字符:“^.{3}$”;


18.只能输入由26个英文字母组成的字符串:“8+$”;


19.只能输入由26个大写英文字母组成的字符串:“9+$”;


20.只能输入由26个小写英文字母组成的字符串:“10+$”;


21.验证是否含有^%&',;=?等 ¨ 字符: "[^“]+”;


22.只能输入汉字:“11{0,}$”(这里使用了Unicode字符码哦);


23.验证URL:“^https?😕/([\w-]+.)+[\w-]+(/[\w-./?%&=]*)?$”;


24.验证一年的12个月:"^(0?[1-9]|1[0-2])$"正确格式为:“01"~"09"和"10"~"12”;


25.验证一个月的31天:"^((0?[1-9])|((1|2)[0-9])|30|31)$"正确格式为;“01"~"09”、"10"~"29"和“30”~“31”;


26.获取日期正则表达式:“^\d{4}[年|-|.]\d{\1-\12}[月|-|.]\d{\1-\31}日?$”(可用来匹配大多数年月日信息);


27.匹配双字节字符(包括汉字在内):“[^\x00-\xff]”(可以用来计算字符串的长度(一个双字节字符长度计2,ASCII字符计1));


28.匹配空白位置"[\f\n\r\t\v]"(可以用来删除空白行);


29.匹配HTML标记的正则表达式:“<(\S?)[^>]>.?</>|<.? />”(这个也仅仅能匹配部分,对于复杂的嵌套标记依旧无能为力);


30.匹配首尾空白字符的正则表达式:"^\s|\s$"(可以用来删除行首行尾的空白字符(包括空格、制表符、换页符等等),非常有用的表达式);**


31.匹配网址URL的正则表达式:“[a-zA-z]+://[^\s]*”;


32.匹配帐号是否合法(字母开头,允许5-16字节,允许字母数字下划线):“12[a-zA-Z0-9_]{4,15}$”;


33.匹配腾讯QQ号:“[1-9][0-9]{4,10}”;


34.匹配中国邮政编码:“[1-9]\d{5}(?!\d)”(中国邮政编码为6位数字);


35.匹配ip地址:“([1-9]{1,3}.){3}[1-9]”(提取ip地址时有用);


36.匹配MAC地址:(“[A-Fa-f0-9]{2}😃{5}[A-Fa-f0-9]”。


1.0-9 ↩︎


2.a-zA-Z ↩︎


3.A-Za-z0-9 ↩︎


4.0-9 ↩︎


5.0-9 ↩︎


6.0-9 ↩︎


7.0-9 ↩︎


8.A-Za-z ↩︎


9.A-Z ↩︎


10.a-z ↩︎


11.\u4e00-\u9fa5 ↩︎


12.a-zA-Z ↩︎

目录
相关文章
|
3月前
|
算法 测试技术 C#
【动态规划】【字符串】C++算法:正则表达式匹配
【动态规划】【字符串】C++算法:正则表达式匹配
|
1月前
|
存储 JavaScript API
C++ 正则表达式库 std::basic_regex 中文手册(API说明来自cppreference.com)
C++ 正则表达式库 std::basic_regex 中文手册(API说明来自cppreference.com)
26 0
|
1月前
|
Linux Perl
使用awk和正则表达式过滤文本或字符串 - 详细指南和示例
使用awk和正则表达式过滤文本或字符串 - 详细指南和示例
68 0
|
6月前
|
算法 C++
剑指offer(C++)-JZ19:正则表达式匹配(算法-动态规划)
剑指offer(C++)-JZ19:正则表达式匹配(算法-动态规划)
|
6月前
|
C# C++
C++ 利于宏模拟C#的正则表达式
C++ 利于宏模拟C#的正则表达式
|
6月前
|
C++ Windows Perl
[笔记]c++基础实践《二》regex正则表达式
[笔记]c++基础实践《二》regex正则表达式
|
7月前
|
Unix Linux
如何在 Linux 中使用 Grep 和正则表达式进行文本搜索?
如何在 Linux 中使用 Grep 和正则表达式进行文本搜索?
197 5
|
8月前
|
C语言 C++
C++和C语言打开文本方式对比关于——编程小总结(五)
C++和C语言打开文本方式对比关于——编程小总结(五)
49 0
|
8月前
|
C++
C++正则表达式
C++正则表达式
|
8月前
|
移动开发 小程序 JavaScript
【C++】C++ 标准库 — 正则表达式
关于 C++ 标准库中正则表达式的使用 std::regex
130 0

热门文章

最新文章