• 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]dd{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 << "
    Input 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 << "
    SYSTEM 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 << "
    
    " << test_str;
    while (std::regex_search(iter,iterEnd,match_result,reg2))
    {
    	cout << "
    Match: " << 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  	");
    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

  • 相关阅读:
    297. Serialize and Deserialize Binary Tree
    331. Verify Preorder Serialization of a Binary Tree
    332. Reconstruct Itinerary
    329. Longest Increasing Path in a Matrix
    319. Bulb Switcher
    292. Nim Game
    299. Bulls and Cows
    Ice Cream Tower Gym
    B
    C
  • 原文地址:https://www.cnblogs.com/cmranger/p/4753668.html
Copyright © 2020-2023  润新知