C++正則表達式


正則表達式是處理文本強有力的工具,它使用一套復雜且完善的語法規則,能夠解決文本處理領域的絕大多數問題,諸如驗證、匹配、查找、替換等等,而這些問題用通常的字符串算法是很難解決的。

C++11正式加入了regex庫,下面通過幾個簡單的例子介紹一下regex庫的使用。
有關正則表達式的語法知識,參考這里

要使用regex庫,要包含頭文件#include <regex>

類摘要

basic_regex

template<class _Elem,
	class _RxTraits = regex_traits<_Elem> >
	class basic_regex
		: public _Regex_base
	{	//
...
typedef basic_regex<char> regex;
typedef basic_regex<wchar_t> wregex;

該類封裝了正則表達式的解析和編譯,是正則表達式的基本類。一般有兩種特化regexwregex分別對應窄字符和寬字符。
構造一個正則表達式很簡單:

string regex_str("^(\\d{6})((1|2)\\d{3})((0|1)\\d)([0-3]\\d)(\\d{3}(X|\\d))$");
std::regex pattern(regex_str,std::regex::icase);

match_results
該類保存了正則表達式匹配的結果。match_results為正則表達式的匹配結果提供了一個類似容器的視圖,可以用size()和empty()判斷匹配結果中子表達式的數量,operator[]返回低i個子表達式。如果i==0,則返回整個表達式的匹配對象。
match_results有以下特化方式:

typedef match_results<const char *> cmatch;
typedef match_results<const wchar_t *> wcmatch;
typedef match_results<string::const_iterator> smatch;
typedef match_results<wstring::const_iterator> wsmatch;  

sub_match
該模板類是一個類似迭代器的對象,繼承自std::pair,用來表示一個與子表達式匹配的序列,可以把它當作一個字符區間。

正則匹配
自由函數regex_match()用來檢查一個字符串是否完全匹配一個正則表達式,返回bool結果。

//匹配身份證號碼
// ^\d{6}(1|2)\d{3}(0|1)\d[0-3]\d\d{3}(X|\d)$
string regex_str("^(\\d{6})((1|2)\\d{3})((0|1)\\d)([0-3]\\d)(\\d{3}(X|\\d))$");
std::regex pattern(regex_str,std::regex::icase);//忽略字母大小寫

string id("61251719901212444X");
assert(std::regex_match(id,pattern) == true);

// [a-zA-Z0-9_-]+@[a-zA-Z0-9]+\.[a-zA-Z0-9]+  郵箱簡單正則
string mail_reg_str("^[a-zA-Z0-9_-]+@[a-zA-Z0-9]+\\.[a-zA-Z0-9]+$");
std::regex mail_reg(mail_reg_str,std::regex::icase);

assert(std::regex_match("chm--1989@163.com",mail_reg) == true);

使用正則匹配結果
使用match_results來提取匹配結果。

void IPTest()
{
	//識別一個IP地址,並打印各個部分
	//輸入exit退出程序
	bool isInputEnd = false;
	//(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})
	//有四個子表達式,括號中的內容為一個子表達式
	std::regex ip_reg("(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})\\.(\\d{1,3})");
	std::smatch matchResult;
	const string exitStr("EXIT");
	while (!isInputEnd)
	{
		cout << "\nInput a IP address:";
		string inputStr;
		std::getline(std::cin,inputStr);
		if (inputStr.empty())
		{
			continue;
		}
		
		string tmpStr(inputStr);
		std::transform(tmpStr.begin(),tmpStr.end(),tmpStr.begin(),toupper);
		if (tmpStr == exitStr)
		{
			cout << "\nSYSTEM EXIT!";
			isInputEnd = true;
			continue;
		}
		//正則匹配
		if (std::regex_match(inputStr,matchResult,ip_reg))
		{
			cout << "Match: ";
			//打印子表達式結果
			for (size_t i = 1; i < matchResult.size(); ++i)
			{
				cout << matchResult[i] << " ";
			}
		}
		else
		{
			cout << "Not Match!";
		}
		
	}
}

運行如下:
reg_ip

正則查找
regex_search()regex_match的區別是:regex_match要求輸入的字符串必須要與正則表達式完全匹配,而regex_search則檢測輸入表達式中是否包含正則表達式,即存在一個匹配正則表達式的子串。

//搜索輸入字符串中所有滿足正則表達式 \d{3} 的子串
std::regex reg2("\\d{3}");
string test_str("abc12312a--1b234-7890abc567");
string::const_iterator iter = test_str.begin();
string::const_iterator iterEnd = test_str.end();
std::smatch match_result;
cout << "\n\n" << test_str;
while (std::regex_search(iter,iterEnd,match_result,reg2))
{
	cout << "\nMatch: " << match_result[0];
	iter = match_result[0].second; //更新搜索起始位置
}

正則替換
regex_repalce

template<class _RxTraits,
	class _Elem>
	_STD basic_string<_Elem> regex_replace(
		const _STD basic_string<_Elem>& _Str,
		const basic_regex<_Elem, _RxTraits>& _Re,
		const _STD basic_string<_Elem>& _Fmt,
		regex_constants::match_flag_type _Flgs =
			regex_constants::match_default)
	{	// search and replace
...

regex_replace 在整個字符序列中查找正則表達式e的所有匹配。這個算法每次成功匹配后,就根據參數fmt對匹配字符串進行格式化。

//使用regex_replace 實現trim功能,去掉字符串前后的空白字符
std::regex reg1("^(\\s)*");
std::regex reg2("\\s*$");

string test_str("  abc  \t");
string t("");
test_str = std::regex_replace(test_str,reg1,t);	//trim_left
test_str = std::regex_replace(test_str,reg2,t); //trim_right

測試結果如下:
regex_repalce_png


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM