C/C++可以用正则表达式吗?
C/C++可以用正则表达式吗?
答案肯定是可以的
,那么,今天一个简单的输入scanf
带你走进正则的世界
#include<stdio.h>
int main()
{
printf("input digate:");
char str[100];
scanf("%[0-9]", str); //输入123456abc
printf("%s", str); //打印123456
}
在scanf时输入任何一串以数字开始的字符,那么str里面只会保存字符里面的第一串数字
input digate:123456abc
123456
先给出一些简单的正则
限定符 |
含义 |
---|---|
%[0-9] |
数字集合 |
%[^0-9] |
非数字集合 |
%[a-zA-Z] |
字母集合 |
%[^a-zA-Z] |
非字母集合 |
预热好了,正题开始...
若要判断一个输入的QQ号是否有效,如何判断?
判断步骤:
- 长度大于5,小于等于11;
- 首位不能为0;
- 是否为纯数字?
C++string处理:
#include<iostream>
using namespace std;
int main()
{
string qq = "7466a2063";
if (qq.length() >= 5 && qq.length() <= 11){
// 2. 判断是否非'0'开头
if (qq[0] != '0'){
// 3. 判断是否为纯数字
for each (char var in qq){
cout << var;
if (var < '0' || var > '9'){
cout << "不存在" << endl;
return 0;
}
}
cout << "存在" << endl;
}
else{
cout << "不存在" << endl;
}
}
else{
cout << "不存在" << endl;
}
return 0;
}
虽然功能实现了但是非常麻烦
正则处理:
#include<iostream>
#include<regex>
using namespace std;
int main()
{
regex qq_reg("[1-9]\d{4,11}");
string qq = "746632063";
smatch result;
bool ret = regex_match(qq, result, qq_reg);
cout << (ret ? "存在" : "不存在") << endl;
return 0;
}
笑出了猪叫,一行正则匹配就解决了
是不是很方便呢?那么接下来便来看看C++如何使用正则表达式。
正则程序库(regex)
「正则表达式」就是一套表示规则的式子,专门用来处理各种复杂的操作。
std::regex是C++用来表示正则表达式(regular expression)的库,于C++11加入,它是class std::basic_regex<>
针对char类型的一个特化,还有一个针对wchar_t类型的特化为std::wregex。
正则文法(regex syntaxes)
std::regex默认使用是ECMAScript文法,这种文法比较好用,且威力强大,常用符号的意义如下:
符号 |
意义 |
---|---|
^ |
匹配行的开头 |
$ |
匹配行的结尾 |
. |
匹配任意单个字符 |
[…] |
匹配[]中的任意一个字符 |
(…) |
设定分组 |
转义字符 |
|
d |
匹配数字[0-9] |
D |
d 取反 |
w |
匹配字母[a-z],数字,下划线 |
W |
w 取反 |
s |
匹配空格 |
S |
s 取反 |
+ |
前面的元素重复1次或多次 |
* |
前面的元素重复任意次 |
? |
前面的元素重复0次或1次 |
{n} |
前面的元素重复n次 |
{n,} |
前面的元素重复至少n次 |
{n,m} |
前面的元素重复至少n次,至多m次 |
| |
逻辑或 |
上面列出的这些都是非常常用的符号,靠这些便足以解决绝大多数问题了。
匹配(Match)
字符串处理常用的一个操作是匹配,即字符串和规则恰好对应,而用于匹配的函数为std::regex_match()
,它是个函数模板
bool regex_match(string s,regex pattern)
bool regex_match(string s,smatch result,regex pattern)
bool regex_match(s.cbegin()+i,s.cend(),smatch result,regex pattern) //从字符串的某个位置开始匹配?
我们直接来看例子:
#include<iostream>
#include<regex>
using namespace std;
int main()
{
/*匹配*/
regex pattern("^1[3578]\d{9}$"); //1开头,后面[3578]中的一个,九个数字
string s = "17779637570";
smatch result;
bool ismatch = regex_match(s, result, pattern);
if (ismatch)
{
cout << "匹配成功:" << result[0] << endl;
}
else
cout << "匹配失败" << endl;
return 0;
}
匹配成功:17779637570
匹配成功并返回匹配到的结果
搜索(Search)
搜索与匹配非常相像,其对应的函数为std::regex_search
,也是个函数模板,用法和regex_match一样,不同之处在于搜索只要字符串中有目标出现就会返回,而非完全匹配。
bool regex_search(string s,regex pattern)
bool regex_search(string s,smatch result,regex pattern)
bool regex_search(s.cbegin()+i,s.cend(),smatch result,regex pattern) //从字符串的某个位置开始匹配?
搜索给定字符串中是否存在与模式匹配的子串,如果存在则返回true。
同样可以用smatch result
记录结果,但不同的是result[0]记录的是整个字符串中从左往右第一个匹配模式的子串。
假如有多个子串符合模式,若想知道result[0]中存储的是第几个子串,可以用result.position()
函数,返回数从0开始。
我们直接来看例子:
#include<iostream>
#include<regex>
using namespace std;
int main()
{
regex pattern("\d+"); /*匹配一个到无穷个数字*/
string s = "51x41+(5-13/2)x3a";
smatch result;
string::const_iterator iter_begin = s.cbegin();
string::const_iterator iter_end = s.cend();
while (regex_search(iter_begin, iter_end, result, pattern))
{
cout << "查找成功:" << result[0] << endl;
cout << "查找结果子串的在源串中的迭代器位置" << *result[0].first << endl;
cout << "查找结果子串的在源串后面的位置" << *result[0].second << endl;
iter_begin = result[0].second; //更新迭代器位置
}
return 0;
}
查找成功:51
查找结果子串的在源串中的迭代器位置5
查找结果子串的在源串后面的位置x
查找成功:41
查找结果子串的在源串中的迭代器位置4
查找结果子串的在源串后面的位置+
查找成功:5
查找结果子串的在源串中的迭代器位置5
查找结果子串的在源串后面的位置-
查找成功:13
查找结果子串的在源串中的迭代器位置1
查找结果子串的在源串后面的位置/
查找成功:2
查找结果子串的在源串中的迭代器位置2
查找结果子串的在源串后面的位置)
查找成功:3
查找结果子串的在源串中的迭代器位置3
查找结果子串的在源串后面的位置a
替换(Replace)
最后一种操作称为替换,即将正则表达式内容替换为指定内容,regex库用模板函数std::regex_replace
提供替换操作。
string regex_replace(string s,regex p,string replace_str) //有其他重载用法
现在,给定一个数据为"he...ll..o, worl..d!"
, 思考一下,如何去掉其中误敲的“.”?
#include<iostream>
#include<regex>
using namespace std;
int main()
{
char data[] = "he...ll..o, worl..d!";
regex reg("\."); //正则匹配点.
cout << regex_replace(data, reg, ""); //将正则匹配到的点替换成无,即删除点
return 0;
}
hello, world!
删除了没必要的点,是不是贼方便...
对字符串data中与模式匹配的所有子串进行相应的字符串替换,替换字符串引用匹配子串中的内容,引用方法如下
匹配第n
个捕捉组的字符串。例如$l
表示第一个捕捉组,$2
表示第二个,依此类推
#include<iostream>
#include<regex>
using namespace std;
int main()
{
char data[] = "001-Neo,002-Lucia";
regex reg("(\d+)-(\w+)");
cout << regex_replace(data, reg, "$1 name=$2");
return 0;
}
001 name=Neo,002 name=Lucia
正则在C/C++里面还有其他应用吗?
答案毋庸置疑,有的,在Linux操作系统中正则表达式常用来查找文本里面指定的内容,如果阅读量可观,后期还会发布Linxu下字符串匹配查找grep
的详细使用和实战
正则表达式更为详细的讲解在下面两篇推送中,Python的,可以看下正则匹配元字符,另外这个号主文章写得不错,可以点点关注。
那么这期就到这里,周末见..
- Gershon Dublon & Nan Zhao:用传感器网络感知世界
- 即日起珠海可用微信乘公交,腾讯乘车码助力智慧城市建设
- 利用mk-table-checksum监测Mysql主从数据一致性操作记录
- mysql主从同步(4)-Slave延迟状态监控
- 浏览器窗口尺寸改变时的图片自动重新定位
- Mongodb主从复制/ 副本集/分片集群介绍
- Paul-Adrien Menez:互联网与抵制食物浪费的故事
- DRBD详细解说及配置过程记录
- Servant:基于Web的IIS管理工具
- Web前端知识体系精简——CSS 篇
- 几种异步操作方式
- 今天的面试小记
- objective-C中的序列化(serialize)与反序列化(deserialize)
- 微信小程序 template 模板功能实现循环
- 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 数组属性和方法
- 实用,完整的HTTP cookie指南
- django-URL之从URL中获取关键字(七)
- springmvc之使用POJO作为参数
- 【猫狗数据集】利用tensorboard可视化训练和测试过程
- springmvc之视图解析流程
- 【猫狗数据集】从命令行接收参数
- django-URL重定向(八)
- Jetpack新成员,App Startup一篇就懂
- python之利用魔术方法实现自己定义的二维向量
- 【猫狗数据集】使用top1和top5准确率衡量模型
- django-URL反向解析Reverse(九)
- spring之如何在web应用中使用?
- 【猫狗数据集】使用预训练的resnet18模型
- django-URL应用命名空间(十)
- 【colab pytorch】模型权重初始化