linux下c/c++实例之五正则表达式字符串匹配

一、简介

       标准的C和C++不支持正则表达式,但有一些函数库可以辅助C/C++程序员完成这一功能。正则表达式常用函数:编译正则表达式 regcomp()、匹配正则表达式 regexec()、释放正则表达式 regfree()。

二、详解

1、代码

regcomp.cpp:

[html] view plain copy
  1. #include <iostream>  
  2. #include <stdio.h>  
  3. #include <stdlib.h>  
  4. #include <string>  
  5. #include <regex.h>  
  6. #include <assert.h>  
  7. #include <string.h>  
  8. using namespace std;  
  9.   
  10. int find_first(string input, string pattern, string &out){  
  11.     regex_t reg;  
  12.     regmatch_t pm[1];  
  13.     int  iret = 0;  
  14.     out = "";  
  15.     /*编译正则表达式*/  
  16.     iret = regcomp(&reg, pattern.c_str(), REG_EXTENDED|REG_NEWLINE);  
  17.     if (iret != 0){  
  18.         return -1;  
  19.     }  
  20.     iret = regexec(&reg, input.c_str(), 1, pm, 0);  
  21.     if (iret == REG_NOMATCH){  
  22.         out = "";  
  23.         iret = input.length();  
  24.     }else if (iret != 0) {  
  25.         return -2;  
  26.     }else{  
  27.         out = input.substr(pm[0].rm_so,pm[0].rm_eo-pm[0].rm_so);  
  28.         iret = pm[0].rm_eo;  
  29.     }  
  30.     regfree(&reg);  
  31.     return iret;  
  32. }  
  33.   
  34. int find_first(char *buff, char *pattern, char *outdata){  
  35.     regex_t reg;  
  36.     regmatch_t pm[1];  
  37.     int  status = 0;  
  38.     /*编译正则表达式*/  
  39.     status = regcomp(&reg, pattern, REG_EXTENDED|REG_NEWLINE);  //扩展正则表达式和识别换行符  
  40.     if (status != 0){    //成功返回0  
  41.         return -1;  
  42.     }  
  43.     status = regexec(&reg, buff, 1, pm, 0);  
  44.     if (status == REG_NOMATCH){  
  45.         printf("no match!\n");  
  46.         status = -1;  
  47.     }  
  48.     else if (status != 0) {  
  49.         return -2;  
  50.     }  
  51.     else if (status == 0) {  
  52.         int i, j;  
  53.         for (i = pm[0].rm_so, j = 0; i pm[0].rm_eo; i++, j++) {  
  54.             outdata[j] = buff[i];  
  55.         }  
  56.         outdata[i] = '\0';  
  57.     }  
  58.     regfree(&reg);  
  59.     return status;  
  60. }  
  61.   
  62. int find_all(char *buff, char *pattern, char result[][20]){   //返回匹配个数  
  63.     regex_t reg;  
  64.     regmatch_t pm[1];  
  65.     int  status = 0;  
  66.     char * p = buff;  
  67.     int count = 0;  
  68.     /*编译正则表达式*/  
  69.     status = regcomp(&reg, pattern, REG_EXTENDED|REG_NEWLINE);  //扩展正则表达式和识别换行符  
  70.     if (status != 0){    //成功返回0  
  71.         return -1;  
  72.     }  
  73.     int i = 0, j, k;  
  74.     while((status = regexec(&reg, p, 1, pm, 0)) == 0) {  
  75.         for(j = pm[0].rm_so, k = 0; j pm[0].rm_eo; j++) {  
  76.             result[i][k++] = p[j];  
  77.         }  
  78.         result[i][k] = '\0';  
  79.         i++;  
  80.         p += pm[0].rm_eo;  
  81.         count++;  
  82.         if (*p == '\0')  break;  
  83.     }  
  84.     regfree(&reg);  
  85.     return count;  
  86. }  
  87. int print_file(const char *file_name, const char *pattern)  
  88. {  
  89.     regex_t reg;  
  90.     regmatch_t pm[1];  
  91.     int  status = 0;  
  92.     int count = 0;  
  93.     FILE *fp = fopen(file_name, "r+");  
  94.     assert(fp);  
  95.     char buff[1024] = {0};  
  96.     char output[1024] = {0};  
  97.     /*编译正则表达式*/  
  98.     status = regcomp(&reg, pattern, REG_EXTENDED|REG_NEWLINE);  //扩展正则表达式和识别换行符  
  99.     assert(status == 0);  
  100.     while(fgets(buff, sizeof(buff), fp)) {     //循环读取文件  
  101.         char * p = buff;  
  102.         while(1) {  
  103.             status = regexec(&reg, p, 1, pm, 0);  
  104.             if (status == 0) {  //匹配成功  
  105.                 count++;  
  106.                 strncpy(output, p + pm[0].rm_so, pm[0].rm_eo - pm[0].rm_so);  
  107.                 cout<<"匹配:"<<output<<endl;  
  108.                 p += pm[0].rm_eo;  
  109.             }  
  110.             else {  
  111.                 break;  
  112.             }  
  113.         }  
  114.     }  
  115.     regfree(&reg);  
  116.     return count;  
  117. }  
  118. int main()  
  119. {  
  120.     char result[20][20] = {0};  
  121.     char buf[] = "1231a4568b789c234";  
  122.     char pattern[] = "[0-9]{3}";  
  123.   
  124.     char resultfirst[20] = {0};  
  125.     find_first(buf, pattern, resultfirst);  
  126.     cout<<strlen(resultfirst) << ":" <resultfirst<<endl;  
  127.     cout << "***************************" <<endl;  
  128.   
  129.     int count = find_all(buf, pattern, result);  
  130.     for (int i = 0; i count; i++) {  
  131.         cout<<"result:"<<"i="<<i+1<<"----"<<result[i]<<endl;  
  132.     }  
  133.     cout << "***************************" <<endl;  
  134.     count = print_file("test.txt", "[0-9]{5}");  
  135.     cout<<"匹配的个数:"<<count<<endl;  
  136.     return 0;  
  137. }  

 

2、编译运行

[html] view plain copy
  1. g++ -o regcomp regcomp.cpp  
  2. ./regcomp  

当前目录下的测试文件test.txt的内容:

[html] view plain copy
  1. abc12345678  
  2. ddd55555555hhh  
  3. 123456  

三、总结

(1)正则表达式的语法可参考http://deerchao.net/tutorials/regex/regex-1.htm、在线正则表达式测试http://tool.oschina.net/regex
(2)若有建议,请留言,在此先感谢

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值