正则表达式

目录

1. 正则表达式的语法

2. 正则表达式的三个常用函数或功能

1). regex_match(全文匹配)

2). regex_search (搜索)

3). regex_replace(替换)

3. python中的正则使用

4. linux下正则的使用

5. 帮助网站

6. 参考



1. 正则表达式的语法

 

参考:https://www.runoob.com/regexp/regexp-syntax.html

注意:Java中可以使用自定义分组,非常方便,C++中貌似不支持自定义分组,需要自己实现逻辑,在使用过程中,我暂时是用的二次匹配策略来实现Java中自定义分组捕获的功能。

2. 正则表达式的三个常用函数或功能

1). regex_match(全文匹配)

要求整个字符串符合匹配规则,返回bool类型

string str = "Hello_2018";
smatch result;
regex pattern("(.{5})_(\\d{4})");	//匹配5个任意单字符 + 下划线 + 4个数字

if (regex_match(str, result, pattern))
{
	cout << result[0] << endl;		//完整匹配结果,Hello_2018
	cout << result[1] << endl;		//第一组匹配的数据,Hello
	cout << result[2] << endl;		//第二组匹配的数据,2018
	cout<<"结果显示形式2"<<endl;
	cout<< result.str() << endl;	//完整结果,Hello_2018
	cout<< result.str(1) << endl;	//第一组匹配的数据,Hello
	cout << result.str(2) << endl;	//第二组匹配的数据,2018
}

//遍历结果
for (int i = 0; i < result.size(); ++i)
{
	cout << result[i] << endl;
}

result[]与result.str()这两种方式能够获得相同的值,数组用起来更方便。

在匹配规则中,以括号()的方式来划分组别,实例中的规则共有两个括号,所以共有两组数据。

2). regex_search (搜索)

search是搜索匹配,即搜索字符串中存在符合规则的子字符串。

match和search的比较

cout << regex_match("123", regex("\\d")) << endl;		//结果为0
cout << regex_search("123", regex("\\d")) << endl;		//结果为1

实例

string str = "Hello 2018, Bye 2017";
smatch result;
regex pattern("\\d{4}");	//匹配四个数字

//迭代器声明
string::const_iterator iterStart = str.begin();
string::const_iterator iterEnd = str.end();
string temp;
while (regex_search(iterStart, iterEnd, result, pattern))
{
	temp = result[0];
	cout << temp << " ";
	iterStart = result[0].second;	//更新搜索起始位置,搜索剩下的字符串
}

输出结果:2018 2017

补充




//#include "regex.hpp"
#include <regex>
#include <string>
#include <vector>
#include <iostream>
using namespace std;
int test_regex_match()
{
	std::string pattern{ "\\d{3}-\\d{8}|\\d{4}-\\d{7}" }; // fixed telephone
	std::regex re(pattern);
	std::vector<std::string> str{ "010-12345678", "0319-9876543", "021-123456789" };
	/* std::regex_match:
	 判断一个正则表达式(参数re)是否匹配整个字符序列str,它主要用于验证文本
	 注意,这个正则表达式必须匹配被分析串的全部,否则返回false;如果整个序列被成功匹配,返回true
	*/
	for (auto tmp : str) {
		bool ret = std::regex_match(tmp.c_str(), re);
		if (ret) cout << tmp.c_str() << " can match\n" << endl;
		else cout << tmp.c_str() << " can not match\n" << endl;
	}
	return 0;
}
int test_regex_search()
{
	std::string pattern{ "http|hppts://\\w*$" }; // url
	std::regex re(pattern);
	std::vector<std::string> str{ "http://blog.csdn.net/fengbingchun", "https://github.com/fengbingchun",
								  "abcd://124.456", "abcd https://github.com/fengbingchun 123" };
	/* std::regex_search:
	 类似于regex_match,但它不要求整个字符序列完全匹配
	 可以用regex_search来查找输入中的一个子序列,该子序列匹配正则表达式re
	*/
	for (auto tmp : str) {
		bool ret = std::regex_search(tmp, re);
		if (ret) cout << tmp.c_str() << " can match" << endl;
		else cout << tmp.c_str() << " can not match" << endl;
	}
	return 0;
}
int test_regex_search2()
{
    std::string pattern{ "[a-zA-z]+://[^\\s]*" }; // url
    std::regex re(pattern);
    std::string str{ "my csdn blog addr is: http://blog.csdn.net/fengbingchun , my github addr is: https://github.com/fengbingchun " };
    std::smatch results;
    while (std::regex_search(str, results, re)) {

		

        for (auto x : results)
            std::cout << x << " ";
        std::cout << std::endl;
        str = results.suffix().str();
    }
    return 0;
}

int test_regex_search3()
{
    std::string pattern{ "[a-zA-z]+"}; // url
    std::regex re(pattern);
    std::string str{ "12WE34RT56" };
    std::smatch ms;
    while (std::regex_search(str, ms, re)) {

		for (size_t i = 0; i < ms.size(); ++i)
		{
			std::cout << "第" << i << "个结果:\"" << ms.str(i) << "\" - ";
			std::cout << "起始位置:" << ms.position(i) << "长度" << ms.length(i) << std::endl;
		}
		str = ms.suffix().str();

    }
    return 0;
}



int test_regex_replace()
{
	std::string pattern{ "\\d{18}|\\d{17}X" }; // id card
	std::regex re(pattern);
	std::vector<std::string> str{ "123456789012345678", "abcd123456789012345678efgh",
								  "abcdefbg", "12345678901234567X" };
	std::string fmt{ "********" };
	/* std::regex_replace:
	 在整个字符序列中查找正则表达式re的所有匹配
	 这个算法每次成功匹配后,就根据参数fmt对匹配字符串进行替换
	*/
	for (auto tmp : str) {
		std::string ret = std::regex_replace(tmp, re, fmt);
		cout << "src:" << tmp.c_str() << " , dst:" << ret.c_str() << endl;

	}
	return 0;
}
int test_regex_replace2()
{
    // reference: http://www.cplusplus.com/reference/regex/regex_replace/
    std::string s("there is a subsequence in the string\n");
    std::regex e("\\b(sub)([^ ]*)"); // matches words beginning by "sub"
    // using string/c-string (3) version:
    std::cout << std::regex_replace(s, e, "sub-$2");
    // using range/c-string (6) version:
    std::string result;
    std::regex_replace(std::back_inserter(result), s.begin(), s.end(), e, "$2");
    std::cout << result;
    // with flags:
    std::cout << std::regex_replace(s, e, "$1 and $2", std::regex_constants::format_no_copy);
    std::cout << std::endl;
    return 0;
}



int main_1() {

	//test_regex_match();

	//test_regex_replace();

	test_regex_search3();

	return 0;
}

对于中文,需要使用宽字符,以下是实现中文的匹配和替换匹配的示例

	void init()
	{


		std::wstring digits = L"[零|一|幺|二|两|三|四|五|六|七|八|九]";

		std::wstring digitsWithTen = L"[零|一|幺|二|两|三|四|五|六|七|八|九|十|期]";
		slot = L"number";
		std::wstring p = L"(?:" + digits + L"{3,}" + digitsWithTen + L"*)";

		//p = L"([零|一|幺|二|两|三|四|五|六|七|八|九]{3,}[零|一|幺|二|两|三|四|五|六|七|八|九|十|期]*)";

		std::locale loc("");
		std::wcout.imbue(loc);

		// 表达式选项 - 忽略大小写  
		std::regex_constants::syntax_option_type fl = std::regex_constants::icase;


		// 编译一个正则表达式语句  
		std::wregex regExpress(p, fl);

		pattern = regExpress;

		category = NumberCategory::DIGIT;

	}

    std::wstring translate(std::wstring sentence) {
	std::wstring result = L"";
	int pre, old_last = 0;
	std::wstring key;

	DigitMap *digitmap = DigitMap::GetInstance();

	// 保存查找的结果  
	std::wsmatch ms;

	// 查找  
	while (std::regex_search(sentence, ms, pattern))
	{

		std::wstring value;

		key = ms.str(0);

		if (category == NUMBER)
		{
			value = digitmap->convertNumber(key);
		}
		else
		{
			value = digitmap->convertDigits(key);
		}

		result = result + ms.prefix().str() + value;

		
		sentence = ms.suffix().str();
		
	}

	//不为空说明至少匹配一个,否则返回空串
	if (result != L"")
	{
		result = result + sentence;
	}

	return result;
}

 其中,尤其需要注意的是smatch中prefix和suffix的用法,分别表示匹配字符串在主串中之前和之后的子串。

3). regex_replace(替换)

replace是替换匹配,即可以将符合匹配规则的子字符串替换为其他字符串。

string str = "Hello_2018!";
regex pattern("Hello");	
cout << regex_replace(str, pattern, "") << endl;	//输出:_2018,将Hello替换为""
cout << regex_replace(str, pattern, "Hi") << endl;	//输出:Hi_2018,将Hello替换为Hi

拓展

除了直接替换外,还有可以用来调整字符串内容(缩短、顺序等)

string str = "Hello_2018!";	
regex pattern2("(.{3})(.{2})_(\\d{4})");				//匹配3个任意字符+2个任意字符+下划线+4个数字
cout << regex_replace(str, pattern2, "$1$3") << endl;	//输出:Hel2018,将字符串替换为第一个和第三个表达式匹配的内容
cout << regex_replace(str, pattern2, "$1$3$2") << endl;	//输出:Hel2018lo,交换位置顺序

$n用于表示第n组匹配数据(组这个概念在文章前面部分提到过),所以我们可以利用这种方式来将字符串的内容进行调整。

regex::icase:匹配时忽略大小写。

3. python中的正则使用

https://www.runoob.com/python/python-reg-expressions.html

4. linux下正则的使用

https://blog.csdn.net/windeal3203/article/details/52930947

5. 帮助网站

附上两个写正则表达式常用到的网站

在线正则表达式验证

regexper(显示正则表达式匹配结构)

6. 参考

1. https://blog.csdn.net/qlb7707/article/details/51957415

2. https://blog.csdn.net/qq_34802416/article/details/79307102

  • 1
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值