分享

电话号码及日期时间提取(正则表达式 C语言)

 心不留意外尘 2016-04-12

from http://blog.csdn.net/firstboy0513/article/details/6855991

直接看代码:

PhoneDateExtract.h

  1. /** 
  2.   \brief A define file. 
  3.   \filename : PhoneDateExtract.h 
  4.   \date     : 24-Mar-2011. 
  5.   \version  : 0.1.1 
  6.             : 0.1.2 (modify in 2011-10-08 as 400/800 phone numbers) 
  7.   \author   : Guohua 
  8.  */  
  9.   
  10. #ifndef __PHONE_DATE_EXTRACT_H__  
  11. #define __PHONE_DATE_EXTRACT_H__  
  12.   
  13. /**  
  14.  * @biref 中国大陆区域通用电话号码提取 
  15.  * 正则表达式说明如下 
  16.  *  ( 
  17.  *   ([0-9]{11}) // 11位手机号码 
  18.  *   | 
  19.  *   ( 
  20.  *      (400|800)([0-9\\-]{7,10}) // 400或800号码 
  21.  *      |(([0-9]{4}|[0-9]{3})(-| )?)?([0-9]{7,8})((-| |转)*([0-9]{1,4}))? // 固定电话号码 
  22.  *   ) 
  23.  *  ) 
  24.  * @demo 
  25.  *  char* phone = NULL; 
  26.  *  phone_extract("2011年3月7日 14:03", &phone); 
  27.  *  printf("format phone = [%s]\n", phone); 
  28.  *  free(phone); 
  29.  *  @param str 待处理的字符串 
  30.  * @param phone [output] 提取出的电话号码子串(要注意在外面释放其堆内存) 
  31.  * @return 返回0表示成功,否则出错。 
  32.  */  
  33. int phone_extract(const char* str, char** phone);  
  34.   
  35. /** 
  36.  * @biref 简体中文文本网页时间提取 
  37.  * 正则表达式说明如下 
  38.  * [0-9]{2,4}(-|/|年)            //年份 
  39.  * [0-9]{1,2}(-|/|月)            //月份 
  40.  * [0-9]{1,2}                   //日 
  41.  * [0-9]{1,2}                   //小时 
  42.  * :[0-9]{1,2}                  //分钟 
  43.  * (:[0-9]{1,2})?               //钞 
  44.  * @demo 
  45.  *  char* datetime = NULL; 
  46.  *  datetime_extract("2011年3月7日 14:03", &datetime); 
  47.  *  printf("format datetime = [%s]\n", datetime); 
  48.  *  free(datetime); 
  49.  * @param str 待处理的字符串 
  50.  * @param date [output] 提取出的日期时间子串, 
  51.  * 其格式为“yy-MM-dd hh-mm-ss”的字符串(要注意在外面释放其堆内存) 
  52.  * @return 返回0表示成功,否则出错。 
  53.  */  
  54. int datetime_extract(const char* str, char** date);  
  55.   
  56. #endif // __PHONE_DATE_EXTRACT_H__  



源文件PhoneDateExtract.c

  1. #include "PhoneDateExtract.h"  
  2. #include <string.h>  
  3. #include <stdlib.h>  
  4. #include <stdio.h>  
  5. #include <regex.h>  
  6.   
  7. #define return_if_fail(expr, val) \  
  8. do { \  
  9.     if (!(expr)) return val; \  
  10. }while(0);  
  11.   
  12. /**  
  13.  * @biref 字符串取子串 
  14.  * @param str 原始字符串 
  15.  * @param pos 截取开始位置 
  16.  * @param len 截取长度 
  17.  * @return 子串对应上址,如果返回NULL表示出错。 
  18.  */  
  19. char* substr(const char* str, int pos, int len);  
  20.   
  21. /**  
  22.  * @biref 字符串正向查找 
  23.  * @param src 待处理的主字符串 
  24.  * @param str 要查找的子字符串 
  25.  */  
  26. int find(const char *src, const char *str);  
  27.   
  28. /**  
  29.  * @biref 字符串反向查找 
  30.  * @param src 待处理的主字符串 
  31.  * @param str 要查找的子字符串 
  32.  */  
  33. int rfind(const char *src, const char *str);  
  34.   
  35. /**  
  36.  * @biref 中国大陆区域通用电话号码提取 
  37.  * 正则表达式说明如下 
  38.  *  ( 
  39.  *   ([0-9]{11}) // 11位手机号码 
  40.  *   | 
  41.  *   ( 
  42.  *      (400|800)([0-9\\-]{7,10}) // 400或800号码 
  43.  *      |(([0-9]{4}|[0-9]{3})(-| )?)?([0-9]{7,8})((-| |转)*([0-9]{1,4}))? // 固定电话号码 
  44.  *   ) 
  45.  *  ) 
  46.  * @demo 
  47.  *  char* phone = NULL; 
  48.  *  phone_extract("2011年3月7日 14:03", &phone); 
  49.  *  printf("format phone = [%s]\n", phone); 
  50.  *  free(phone); 
  51.  *  @param str 待处理的字符串 
  52.  * @param phone [output] 提取出的电话号码子串(要注意在外面释放其堆内存) 
  53.  * @return 返回0表示成功,否则出错。 
  54.  */  
  55. int phone_extract(const char* str, char** phone)  
  56. {  
  57.     // 正则表示式提取  
  58.     const char* pattern_date = "(([0-9]{11})|((400|800)([0-9\\-]{7,10})|(([0-9]{4}|[0-9]{3})(-| )?)?([0-9]{7,8})((-| |转)*([0-9]{1,4}))?))";  
  59.     int z = 0;  
  60.     regex_t reg_date, reg_time;  
  61.     regmatch_t pm_date[1], pm_time[1];  
  62.     regcomp(&reg_date, pattern_date, REG_EXTENDED);  
  63.     z = regexec(&reg_date, str, 1, pm_date, 0);  
  64.     regfree(&reg_date);  
  65.     if(0 != z)  
  66.     {  
  67.         fprintf(stderr, " invalid phone number format: [%s]\n", str);  
  68.         *phone = NULL;  
  69.         return -1;  
  70.     }  
  71.     // 保存号码结果  
  72.     char* s_phone = NULL;  
  73.     return_if_fail(s_phone = substr(str,   
  74.         pm_date[0].rm_so,   
  75.         pm_date[0].rm_eo - pm_date[0].rm_so), -1);  
  76.     int n_size = strlen(s_phone);  
  77.     (*phone) = (char*) malloc(n_size + 1);  
  78.     memset((*phone), 0, n_size);  
  79.     strcpy((*phone), s_phone);  
  80.     free(s_phone);  
  81.     return 0;  
  82. }  
  83.   
  84. /** 
  85.  * @biref 简体中文文本网页时间提取 
  86.  * 正则表达式说明如下 
  87.  * [0-9]{2,4}(-|/|年)            //年份 
  88.  * [0-9]{1,2}(-|/|月)            //月份 
  89.  * [0-9]{1,2}                   //日 
  90.  * [0-9]{1,2}                   //小时 
  91.  * :[0-9]{1,2}                  //分钟 
  92.  * (:[0-9]{1,2})?               //钞 
  93.  * @demo 
  94.  *  char* datetime = NULL; 
  95.  *  datetime_extract("2011年3月7日 14:03", &datetime); 
  96.  *  printf("format datetime = [%s]\n", datetime); 
  97.  *  free(datetime); 
  98.  * @param str 待处理的字符串 
  99.  * @param date [output] 提取出的日期时间子串, 
  100.  * 其格式为“yy-MM-dd hh-mm-ss”的字符串(要注意在外面释放其堆内存) 
  101.  * @return 返回0表示成功,否则出错。 
  102.  */  
  103. int datetime_extract(const char* str, char** date)  
  104. {  
  105.     char* datetime = (char*) malloc(20);  
  106.     memset(datetime, 0, 20);  
  107.     *date = datetime;  
  108.     int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0;  
  109.     char* s_num = NULL;  
  110.       
  111.     const char* pattern_date = "[0-9]{2,4}(-|/|年)[0-9]{1,2}(-|/|月)[0-9]{1,2}";  
  112.     const char* pattern_time = "[0-9]{1,2}:[0-9]{1,2}(:[0-9]{1,2})?";  
  113.     int z = 0;  
  114.     regex_t reg_date, reg_time;  
  115.     regmatch_t pm_date[1], pm_time[1];  
  116.       
  117.     // 提取日期  
  118.     regcomp(&reg_date, pattern_date, REG_EXTENDED);  
  119.     z = regexec(&reg_date, str, 1, pm_date, 0);  
  120.     regfree(&reg_date);  
  121.     if(0 != z)  
  122.     {  
  123.         fprintf(stderr, " invalid date format: [%s]\n", str);  
  124.         strcpy(datetime, "2000-01-01 00:00:00");  
  125.         return -1;  
  126.     }  
  127.     char* s_date = NULL;  
  128.     return_if_fail(s_date = substr(str,   
  129.         pm_date[0].rm_so,   
  130.         pm_date[0].rm_eo - pm_date[0].rm_so), -1);  
  131.     int n_offset = 1;  
  132.     int date_l = 0;  
  133.     int date_r = 0;  
  134.     date_l = find(s_date, "-");  
  135.     date_r = rfind(s_date, "-");  
  136.     if(-1 == date_l)  
  137.     {  
  138.         date_l = find(s_date, "/");  
  139.     }  
  140.     if(-1 == date_r || date_r == date_l)  
  141.     {  
  142.         date_r = rfind(s_date, "/");  
  143.     }  
  144.     if(-1 == date_l)  
  145.     {  
  146.         date_l = find(s_date, "年");  
  147.         n_offset = strlen("年");  
  148.     }  
  149.     if(-1 == date_r || date_r == date_l)  
  150.     {  
  151.         date_r = find(s_date, "月");  
  152.         n_offset = strlen("月");  
  153.     }  
  154.     return_if_fail(s_num = substr(s_date, 0, date_l - 0), -1);  
  155.     year = atoi(s_num); free(s_num);  
  156.     if(year < 100) { year += 2000; };  
  157.     return_if_fail(s_num = substr(s_date, \  
  158.         date_l + n_offset, date_r - date_l - n_offset), -1);  
  159.     month = atoi(s_num); free(s_num);  
  160.     return_if_fail(s_num = substr(s_date,   
  161.         date_r + n_offset, strlen(s_date) - date_r - n_offset), -1);  
  162.     day = atoi(s_num); free(s_num);  
  163.     free(s_date);  
  164.       
  165.     // 提取时间  
  166.     regcomp(&reg_time, pattern_time, REG_EXTENDED);  
  167.     z = regexec(&reg_time, str, 1, pm_time, 0);  
  168.     regfree(&reg_time);  
  169.     if(0 != z)  
  170.     {  
  171.         fprintf(stderr, " invalid time format: [%s]\n", str);  
  172.         hour = 0;  
  173.         minute = 0;  
  174.         second = 0;  
  175.         sprintf(datetime, "%04d-%02d-%02d %02d:%02d:%02d",   
  176.             year, month, day, hour, minute, second);  
  177.         return 0;  
  178.     }  
  179.     char* s_time = NULL;  
  180.     return_if_fail(s_time = substr(str, \  
  181.         pm_time[0].rm_so, pm_time[0].rm_eo - pm_time[0].rm_so), -1);  
  182.     int time_l = find(s_time, ":");  
  183.     int time_r = rfind(s_time, ":");  
  184.     return_if_fail(s_num = substr(s_time, 0, time_l - 0), -1);  
  185.     hour = atoi(s_num); free(s_num);  
  186.     if(time_l != time_r)  
  187.     {  
  188.         return_if_fail(s_num = substr(s_time, \  
  189.             time_l + 1, time_r - time_l - 1), -1);  
  190.         minute = atoi(s_num); free(s_num);  
  191.         return_if_fail(s_num = substr(s_time, \  
  192.             time_r + 1, strlen(s_time) - time_r - 1), -1);  
  193.         second = atoi(s_num); free(s_num);  
  194.     }  
  195.     else  
  196.     {  
  197.         return_if_fail(s_num = substr(s_time, \  
  198.             time_l + 1, strlen(s_time) - time_l - 1), -1);  
  199.         minute = atoi(s_num); free(s_num);  
  200.         second = 0;  
  201.     }  
  202.     free(s_time);  
  203.     sprintf(datetime, "%04d-%02d-%02d %02d:%02d:%02d",   
  204.             year, month, day, hour, minute, second);  
  205.     return 0;  
  206. }  
  207.   
  208. char* substr(const char* str, int pos, int len)  
  209. {  
  210.     if(len <= 0)  
  211.     {  
  212.         printf("[*ERROR]: %s: %d: str = [%s], pos = [%d], len = [%d]\n", \  
  213.             __FILE__, __LINE__, str, pos, len);  
  214.         return NULL;  
  215.     }  
  216.       
  217.     char *sp = (char*) malloc(len + 1);  
  218.     sp[len] = 0;  
  219.       
  220.     int i = 0;  
  221.     for(; i < len; i++)  {  
  222.         sp[i] = str[pos + i];  
  223.     }  
  224.       
  225.     return sp;  
  226. }  
  227.   
  228. int find(const char *src, const char *str)  
  229. {  
  230.     int i = 0;  
  231.     int j = 0;  
  232.     int n_len_src = strlen(src);  
  233.     int n_len_str = strlen(str);  
  234.     int n_pos = 0;  
  235.       
  236.     for(i = 0 ; i <= n_len_src - n_len_str; i++) {  
  237.         n_pos = i;  
  238.         for(j = 0 ; j < n_len_str ; j++) {  
  239.             if(*(src + n_pos) != *(str + j)) {  
  240.                 break;  
  241.             }  
  242.             if(j == n_len_str - 1) {  
  243.                 return i;  
  244.             }  
  245.             n_pos++;  
  246.         }  
  247.     }  
  248.     return -1;  
  249. }  
  250.   
  251. int rfind(const char *src, const char *str)  
  252. {  
  253.     int i = 0;  
  254.     int j = 0;  
  255.     int n_len_src = strlen(src);  
  256.     int n_len_str = strlen(str);  
  257.     int n_pos = 0;  
  258.       
  259.     for(i = n_len_src - n_len_str ; i > 0; i--) {  
  260.         n_pos = i;  
  261.         for(j = 0 ; j < n_len_str ; j++) {  
  262.             if(*(src + n_pos) != *(str + j)) {  
  263.                 break;  
  264.             }  
  265.             if(j == n_len_str - 1) {  
  266.                 return i;  
  267.             }  
  268.             n_pos++;  
  269.         }  
  270.     }  
  271.     return -1;  
  272. }  



测试示例test.c

  1. /** 
  2.  * 编译: gcc test.c PhoneDateExtract.c -o test 
  3.  * 执行: ./test 
  4.  * 结果:  
  5.  *  format phone = [800-2142-325] 
  6.  *  format datetime = [2011-03-07 14:03:00] 
  7.  */  
  8.   
  9. #include "PhoneDateExtract.h"  
  10. #include <stdlib.h>  
  11. #include <stdio.h>  
  12.   
  13. int main(int argc, char* argv[])  
  14. {  
  15.     // 中国大陆区域通用电话号码提取  
  16.     char* phone = NULL;  
  17.     phone_extract("电话:800-2142-325", &phone);  
  18.     printf("format phone = [%s]\n", phone);  
  19.     free(phone);  
  20.       
  21.     // 简体中文文本网页时间提取  
  22.     char* datetime = NULL;  
  23.     datetime_extract("2011年3月7日 14:03", &datetime);  
  24.     printf("format datetime = [%s]\n", datetime);  
  25.     free(datetime);  
  26.   
  27.     return 0;  
  28. }  

资源下载:http://download.csdn.net/detail/firstboy0513/3667780


    本站是提供个人知识管理的网络存储空间,所有内容均由用户发布,不代表本站观点。请注意甄别内容中的联系方式、诱导购买等信息,谨防诈骗。如发现有害或侵权内容,请点击一键举报。
    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约