前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >C/C++可以用正则表达式吗?

C/C++可以用正则表达式吗?

作者头像
DeROy
发布2020-08-17 14:19:38
1.1K0
发布2020-08-17 14:19:38
举报
文章被收录于专栏:编程学习基地编程学习基地

C/C++可以用正则表达式吗?

答案肯定是可以的,那么,今天一个简单的输入scanf带你走进正则的世界

代码语言:javascript
复制
#include<stdio.h>
int main()
{
	printf("input digate:");
	char str[100];
	scanf("%[0-9]", str);	//输入123456abc
	printf("%s", str);		//打印123456
}

在scanf时输入任何一串以数字开始的字符,那么str里面只会保存字符里面的第一串数字

代码语言:javascript
复制
input digate:123456abc
123456

先给出一些简单的正则

限定符

含义

%[0-9]

数字集合

%[^0-9]

非数字集合

%[a-zA-Z]

字母集合

%[^a-zA-Z]

非字母集合

预热好了,正题开始...

若要判断一个输入的QQ号是否有效,如何判断?

判断步骤:

  1. 长度大于5,小于等于11;
  2. 首位不能为0;
  3. 是否为纯数字?

C++string处理:

代码语言:javascript
复制
#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;
}

虽然功能实现了但是非常麻烦

正则处理:

代码语言:javascript
复制
#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(),它是个函数模板

代码语言:javascript
复制
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)  //从字符串的某个位置开始匹配?

我们直接来看例子:

代码语言:javascript
复制
#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;
}
代码语言:javascript
复制
匹配成功:17779637570

匹配成功并返回匹配到的结果

搜索(Search)

搜索匹配非常相像,其对应的函数为std::regex_search,也是个函数模板,用法和regex_match一样,不同之处在于搜索只要字符串中有目标出现就会返回,而非完全匹配

代码语言:javascript
复制
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开始。

我们直接来看例子:

代码语言:javascript
复制
#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;
}
代码语言:javascript
复制
查找成功:51
查找结果子串的在源串中的迭代器位置5
查找结果子串的在源串后面的位置x
查找成功:41
查找结果子串的在源串中的迭代器位置4
查找结果子串的在源串后面的位置+
查找成功:5
查找结果子串的在源串中的迭代器位置5
查找结果子串的在源串后面的位置-
查找成功:13
查找结果子串的在源串中的迭代器位置1
查找结果子串的在源串后面的位置/
查找成功:2
查找结果子串的在源串中的迭代器位置2
查找结果子串的在源串后面的位置)
查找成功:3
查找结果子串的在源串中的迭代器位置3
查找结果子串的在源串后面的位置a

替换(Replace)

最后一种操作称为替换,即将正则表达式内容替换为指定内容regex库用模板函数std::regex_replace提供替换操作。

代码语言:javascript
复制
string regex_replace(string s,regex p,string replace_str)	//有其他重载用法

现在,给定一个数据为"he...ll..o, worl..d!", 思考一下,如何去掉其中误敲的“.”?

代码语言:javascript
复制
#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;
}
代码语言:javascript
复制
hello, world!

删除了没必要的点,是不是贼方便...

对字符串data中与模式匹配的所有子串进行相应的字符串替换,替换字符串引用匹配子串中的内容,引用方法如下

代码语言:javascript
复制
匹配第n
个捕捉组的字符串。例如$l
表示第一个捕捉组,$2
表示第二个,依此类推
代码语言:javascript
复制
#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;
}
代码语言:javascript
复制
001 name=Neo,002 name=Lucia

正则在C/C++里面还有其他应用吗?

答案毋庸置疑,有的,在Linux操作系统中正则表达式常用来查找文本里面指定的内容,如果阅读量可观,后期还会发布Linxu下字符串匹配查找grep详细使用实战

正则表达式更为详细的讲解在下面两篇推送中,Python的,可以看下正则匹配元字符,另外这个号主文章写得不错,可以点点关注。

那么这期就到这里,周末见..

本文参与 腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2020-08-12,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 编程学习基地 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • C/C++可以用正则表达式吗?
    • 若要判断一个输入的QQ号是否有效,如何判断?
      • C++string处理:
        • 正则处理:
          • 正则程序库(regex)
            • 正则文法(regex syntaxes)
              • 匹配(Match)
                • 搜索(Search)
                  • 替换(Replace)
                    • 正则在C/C++里面还有其他应用吗?
                    领券
                    问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档