c++中正则表达式的应用(转载汇总)

     看到两种,一种是c++11后自带的正则表达式,一种是boost库中的正则表达式,如下:

 

C++11 正则表达式——实例1(转自http://www.cnblogs.com/zhuyp1015/archive/2012/04/08/2438215.html)

 

 该实例通过一个函数is_email_valid 来检查一个email地址是否是一个正确的格式。如果格式正确则返回true。

#include <regex>

#include <iostream>

#include <string>

 

bool is_email_valid(const std::string& email)

{

  

   const std::regex pattern("(\\w+)(\\.|_)?(\\w*)@(\\w+)(\\.(\\w+))+");

 

   return std::regex_match(email, pattern);

}

 

int main()

{

   std::string email1 = "[email protected]";

   std::string email2 = "[email protected]";

   std::string email3 = "[email protected]";

   std::string email4 = "marius@domain";

 

   std::cout << email1 << " : " << (is_email_valid(email1) ?

      "valid" : "invalid") << std::endl;

   std::cout << email2 << " : " << (is_email_valid(email2) ?

      "valid" : "invalid") << std::endl;

   std::cout << email3 << " : " << (is_email_valid(email3) ?

     "valid" : "invalid") << std::endl;

   std::cout << email4 << " : " << (is_email_valid(email4) ?

     "valid" : "invalid") << std::endl;

 

   return 0;

}

运行结果

     这里对is_email_valid()函数中的正则表达式做一个简短的说明,如果对于正则表示不是很清楚的同学就能很容易理解了。
     const std::regex pattern("(\\w+)(\\.|_)?(\\w*)@(\\w+)(\\.(\\w+))+"); 首先注意‘()’表示将正则表达式分成子表达式,每个‘()’之间的内容表示一个子表达式;‘\’是一个转义字符,‘\\’表示扔掉第二个‘\’的转义特性,‘\w+’表示匹配一个或多个单词,‘+’表示重复一次或者多次,因此第一个子表达式的意思就是匹配一个或者多个单词;接着看第二个子表达式,‘|’表示选择,出现‘.’或者‘_’,后面的‘?’表示该子表示出现一次或者零次,因此第二个子表示表示‘.’或‘_’出现不出现都匹配。第三个子表达式表示出现一个单词,‘*’表示任意个字符。后面的子表示根据已经介绍的内容,已经可以容易理解,就不再赘述。通过对正则表达式匹配模式串的分析,可以容易理解运行结果。

 

下面一个例子通过正则表达式识别和打印IP地址的各个部分:

#include <regex>

#include <iostream>

#include <string>

 

void show_ip_parts(const std::string& ip)

{

   // regular expression with 4 capture groups defined with

   // parenthesis (...)

   const std::regex pattern("(\\d{1,3}):(\\d{1,3}):(\\d{1,3}):(\\d{1,3})");

   // object that will contain the sequence of sub-matches

   std:: match_results<std::string::const_iterator> result;

   // match the IP address with the regular expression

   bool valid = std:: regex_match(ip, result, pattern);

   std::cout << ip << " \t: " << (valid ? "valid" : "invalid")

             << std::endl;

   // if the IP address matched the regex, then print the parts

   if(valid)

   {

      std::cout << "b1: " << result[1] << std::endl;

      std::cout << "b2: " << result[2] << std::endl;

      std::cout << "b3: " << result[3] << std::endl;

      std::cout << "b4: " << result[4] << std::endl;

   }

}

 

int main()

{

   show_ip_parts("1:22:33:444");

   show_ip_parts("1:22:33:4444");

   show_ip_parts("100:200");

 

   return 0;

}

运行结果:

是对正则表达式的模式串做一个说明:首先还是通过‘()’将这个串分成几个子表达式,其中\d表示匹配一个数字,{,}表示数字的个数,例如{1,3}可以理解为匹配一个小于1000的数字(1-3位数都符合匹配要求)。

程序中还使用了match_results类,用来保存匹配的每一个子序列。调用regex_match(ip,result,pattern),表示将ip中与模式串pattern匹配的结果放在result中。

result最后可以通过下标来访问各个匹配的子表达式。

 
      个人觉得比较好用的是boost中的,更全面一些,如下:
 

C++:Regex正则表达式(转自:http://blog.sina.com.cn/s/blog_ac9fdc0b0101oow9.html)

   (2013-08-24 19:16:43)
标签:  

杂谈

分类: C_plus_plus
    不会用C++的Regex是硬伤,下面的内容参考《C++程序设计原理与实践》~~~
****************************************************************************************************
正则表达式语法
     正则表达式的特性分成很多种类,下面的内容是perl类型的Regex。
============================================================================================
特殊含义的字符
.  :任意单个字符
[] :字符集
{} :计数
() :子模式
\  :下一个字符具有特殊含义
*  :0个或多个
+  :一个或多个
?  :0个或一个
|  :或
^  :行的开始;否定
$  :行的结束
===========================================================================================
字符集
\d :一个十进制数字
\l :一个小写字母
\s :一个空白符(空格符,制表符等)
\u :一个大写字母
\w :一个字母(a~z或A~Z)或数字(0~9)或下划线(_)
\D :除了\d之外的字符
\L :除了\l之外的字符
\S :除了\s之外的字符
\U :除了\u之外的字符
\W :除了\w之外的字符
===========================================================================================
重复
{n}  :严格重复n次
{n,} :重复n次或更多次
{n,m}:重复至少n次,至多m次
*    :{0,}
+    :{1,}
?    :{0,1}
===========================================================================================
子模式
    为了指定模式中的子模式,用括号将其括起来
(\d*:)?(\d+):它表示字符串前半部分可以为空,若非空,则是任意长度的数字后接一个冒号,后半部分是一个或多个数字的序列。
===========================================================================================
可选项
     | 表示二选一的概念。
Subject:(FW:| Re:):表示匹配Subject:Fw:或者是Subject:Re:
===========================================================================================
正则表达式错误
    当我们将一个模式富裕regex时,它会对模式进行检查,如果发现模式不合法或过于复杂,无法用于匹配时,它会抛出一个bad_expression异常。
===========================================================================================
下面是一个常用的套路,比较稳~~~

注意一点,编译的时候要指定链接:g++ -Wall -lboost_regex test.cpp -o chen
*****************************************************************************************************
正则表达式方法   
=====================================================================================================
(1)regex_match确定一行字符串是否和指定的正则表达式完全匹配
-----------------------------------------------------------------------
//检查模式是否匹配
  8 #include <boost/regex.hpp>
   9 #include <iostream>
  10 #include <string>
  11
  12 using namespace std;
  13 using namespace boost;
  14
  15 int main()
  16 {
  17     // "\w+\s*(\(\w+,\d+\)\s*)*"
  18     regex pattern("\\w+\\s*(\\(\\w+,\\d+\\)\\s*)*");
  19     cout << pattern << endl;
  20    
  21     string str_1 = "chen (chen,0) (huan,1) (jiang,2)";
  22     string str_2 = "chen(chen,0)(huan,1)(jiang,2)";
  23     string str_3 = "chen";
  24     string str_4 = "(chen,0)(huan,1)(jiang,2)";
  25     string str_5 = "chen (chen,0) (huan,1)(jiang,2) chen";
  26    
  27     vector<string> strings;
  28     strings.push_back(str_1); strings.push_back(str_2);
  29     strings.push_back(str_3); strings.push_back(str_4);
  30     strings.push_back(str_5);
  31    
  32     for(int n = 0 ; n < 5 ; ++n)
  33         if(regex_match(strings[n], pattern))
  34             cout << strings[n] << " is matched" << endl;
  35            
  36     return 0;
  37 }  
结果为:
\w+\s*(\(\w+,\d+\)\s*)*
chen (chen,0) (huan,1) (jiang,2) is matched
chen(chen,0)(huan,1)(jiang,2) is matched
chen is matched
--------------------------------------------------------------------------
//regex_match不仅验证是否匹配,而且可以从中提取出正则表达式括号对应的子串
  8 #include <boost/regex.hpp>
   9 #include <iostream>
  10 #include <string>
  11
  12 using namespace std;
  13 using namespace boost;
  14
  15 int main()
  16 {
  17     // "\w+\s*(\(\w+,\d+\)\s*)*"
  18     regex pattern("\\w+\\s*((\\(\\w+,\\d+\\)\\s*)*)");
  19     cout << pattern << endl;
  20    
  21     string str_1 = "chen (chen,0) (huan,1) (jiang,2)";
  22    
  23     smatch mat;
  24     if(regex_match(str_1, mat, pattern))
  25         for(smatch::iterator iter=mat.begin() ; iter!=mat.end() ; ++iter)
  26             cout << *iter <<endl;
  27            
  28     return 0;
  29 }  
结果为:
\w+\s*((\(\w+,\d+\)\s*)*)
chen (chen,0) (huan,1) (jiang,2)
(chen,0) (huan,1) (jiang,2)
(jiang,2)
注意,这个的regex表达式和上面的不同,将后面的子串(\(\w+,\d+\)\s*)*通过括号合并成一个完整的子串。
=====================================================================================================
(2)regex_search:regex_match是验证是否完全匹配,而regex_search是从一大串string中找出匹配的一小段字符串
---------------------------------------------------------------
 15 int main()
  16 {
  17     regex pattern("\\d+");                           
  18     cout << pattern << endl;
  19    
  20     string str_1 = "chen1234huan12345jiang1234567";
  21    
  22     smatch mat;
  23     if(regex_search(str_1, mat, pattern))
  24         for(smatch::iterator iter=mat.begin() ; iter!=mat.end() ; ++iter)
  25             cout << *iter <<endl;
  26            
  27     return 0;
  28 }  
结果为:
1234
可以看出,regex_search是匹配到字符串中第一个符合条件的模式便会返回。
-------------------------------------------------------------
    下面的方法可以将字符串中所有匹配到的模式,全部提取出来,如下:
 15 int main()
  16 {
  17     regex pattern("\\d+");                           
  18     cout << pattern << endl;
  19    
  20     string str_1 = "chen1234huan12345jiang1234567";
  21     string::const_iterator start = str_1.begin();
  22     string::const_iterator end = str_1.end();
  23    
  24     smatch mat;
  25     while(regex_search(start, end, mat, pattern))
  26     {  
  27         string msg(mat[0].first, mat[0].second);
  28         cout << msg << endl;
  29         start = mat[0].second;
  30     }  
  31    
  32     return 0;
  33 }  
结果是:
\d+
1234
12345
1234567
****************************************************************************************************
(3)关于regex::smatch类型
    smatch类型,前缀s表示"子匹配"的概念。一个smatch本质上是一个子匹配的向量。第一个元素是完整匹配。如果i < smatch.size(),我们将smatch[i]当做一个字符串。对于一个正则表达式,如果最后N个子模式,则smatch.size() = N+1(因为有一个完整的匹配)。
    模式中任何放在括号中的内容都可以作为一个子模式,可以看下面这个例子:
Expression: (ftp|http|https):\/\/((\w+\.)*(\w*))\/([\w\d]+\/{0,1})+ 
String: http://www.foo.com/bar
matches[0] = http://www.foo.com/bar
matches[1] = http
matches[2] = www.foo.com
matches[3] = foo.
matches[4] = com
matches[5] = bar

c++中正则表达式的应用(转载汇总),古老的榕树,5-wow.com

郑重声明:本站内容如果来自互联网及其他传播媒体,其版权均属原媒体及文章作者所有。转载目的在于传递更多信息及用于网络分享,并不代表本站赞同其观点和对其真实性负责,也不构成任何其他建议。