程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C >> 關於C >> 電話號碼及日期時間提取(正則表達式 C語言)

電話號碼及日期時間提取(正則表達式 C語言)

編輯:關於C

 

直接看代碼:

 

PhoneDateExtract.h

 

/**

  \brief A define file.

  \filename : PhoneDateExtract.h

  \date     : 24-Mar-2011.

  \version  : 0.1.1

            : 0.1.2 (modify in 2011-10-08 as 400/800 phone numbers)

  \author   : Guohua

 */ 

 

#ifndef __PHONE_DATE_EXTRACT_H__ 

#define __PHONE_DATE_EXTRACT_H__ 

 

/** 

 * @biref 中國大陸區域通用電話號碼提取

 * 正則表達式說明如下

 *  (

 *   ([0-9]{11}) // 11位手機號碼

 *   |

 *   (

 *      (400|800)([0-9\\-]{7,10}) // 400或800號碼

 *      |(([0-9]{4}|[0-9]{3})(-| )?)?([0-9]{7,8})((-| |轉)*([0-9]{1,4}))? // 固定電話號碼

 *   )

 *  )

 * @demo

 *  char* phone = NULL;

 *  phone_extract("2011年3月7日 14:03", &phone);

 *  printf("format phone = [%s]\n", phone);

 *  free(phone);

 *  @param str 待處理的字符串

 * @param phone [output] 提取出的電話號碼子串(要注意在外面釋放其堆內存)

 * @return 返回0表示成功,否則出錯。

 */ 

int phone_extract(const char* str, char** phone); 

 

/**

 * @biref 簡體中文文本網頁時間提取

 * 正則表達式說明如下

 * [0-9]{2,4}(-|/|年)            //年份

 * [0-9]{1,2}(-|/|月)            //月份

 * [0-9]{1,2}                   //日

 * [0-9]{1,2}                   //小時

 * :[0-9]{1,2}                  //分鐘

 * (:[0-9]{1,2})?               //鈔

 * @demo

 *  char* datetime = NULL;

 *  datetime_extract("2011年3月7日 14:03", &datetime);

 *  printf("format datetime = [%s]\n", datetime);

 *  free(datetime);

 * @param str 待處理的字符串

 * @param date [output] 提取出的日期時間子串,

 * 其格式為“yy-MM-dd hh-mm-ss”的字符串(要注意在外面釋放其堆內存)

 * @return 返回0表示成功,否則出錯。

 */ 

int datetime_extract(const char* str, char** date); 

 

#endif // __PHONE_DATE_EXTRACT_H__ 

www.2cto.com

 

 

源文件PhoneDateExtract.c

 

#include "PhoneDateExtract.h" 

#include <string.h> 

#include <stdlib.h> 

#include <stdio.h> 

#include <regex.h> 

 

#define return_if_fail(expr, val) \ 

do { \ 

    if (!(expr)) return val; \ 

}while(0); 

 

/** 

 * @biref 字符串取子串

 * @param str 原始字符串

 * @param pos 截取開始位置

 * @param len 截取長度

 * @return 子串對應上址,如果返回NULL表示出錯。

 */ 

char* substr(const char* str, int pos, int len); 

 

/** 

 * @biref 字符串正向查找

 * @param src 待處理的主字符串

 * @param str 要查找的子字符串

 */ 

int find(const char *src, const char *str); 

 

/** 

 * @biref 字符串反向查找

 * @param src 待處理的主字符串

 * @param str 要查找的子字符串

 */ 

int rfind(const char *src, const char *str); 

 

/** 

 * @biref 中國大陸區域通用電話號碼提取

 * 正則表達式說明如下

 *  (

 *   ([0-9]{11}) // 11位手機號碼

 *   |

 *   (

 *      (400|800)([0-9\\-]{7,10}) // 400或800號碼

 *      |(([0-9]{4}|[0-9]{3})(-| )?)?([0-9]{7,8})((-| |轉)*([0-9]{1,4}))? // 固定電話號碼

 *   )

 *  )

 * @demo

 *  char* phone = NULL;

 *  phone_extract("2011年3月7日 14:03", &phone);

 *  printf("format phone = [%s]\n", phone);

 *  free(phone);

 *  @param str 待處理的字符串

 * @param phone [output] 提取出的電話號碼子串(要注意在外面釋放其堆內存)

 * @return 返回0表示成功,否則出錯。

 */ 

int phone_extract(const char* str, char** phone) 

    // 正則表示式提取 

    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}))?))"; 

    int z = 0; 

    regex_t reg_date, reg_time; 

    regmatch_t pm_date[1], pm_time[1]; 

    regcomp(&reg_date, pattern_date, REG_EXTENDED); 

    z = regexec(&reg_date, str, 1, pm_date, 0); 

    regfree(&reg_date); 

    if(0 != z) 

    { 

        fprintf(stderr, " invalid phone number format: [%s]\n", str); 

        *phone = NULL; 

        return -1; 

    } 

    // 保存號碼結果 

    char* s_phone = NULL; 

    return_if_fail(s_phone = substr(str,  

        pm_date[0].rm_so,  

        pm_date[0].rm_eo - pm_date[0].rm_so), -1); 

    int n_size = strlen(s_phone); 

    (*phone) = (char*) malloc(n_size + 1); 

    memset((*phone), 0, n_size); 

    strcpy((*phone), s_phone); 

    free(s_phone); 

    return 0; 

 

/**

 * @biref 簡體中文文本網頁時間提取

 * 正則表達式說明如下

 * [0-9]{2,4}(-|/|年)            //年份

 * [0-9]{1,2}(-|/|月)            //月份

 * [0-9]{1,2}                   //日

 * [0-9]{1,2}                   //小時

 * :[0-9]{1,2}                  //分鐘

 * (:[0-9]{1,2})?               //鈔

 * @demo

 *  char* datetime = NULL;

 *  datetime_extract("2011年3月7日 14:03", &datetime);

 *  printf("format datetime = [%s]\n", datetime);

 *  free(datetime);

 * @param str 待處理的字符串

 * @param date [output] 提取出的日期時間子串,

 * 其格式為“yy-MM-dd hh-mm-ss”的字符串(要注意在外面釋放其堆內存)

 * @return 返回0表示成功,否則出錯。

 */ 

int datetime_extract(const char* str, char** date) 

    char* datetime = (char*) malloc(20); 

    memset(datetime, 0, 20); 

    *date = datetime; 

    int year = 0, month = 0, day = 0, hour = 0, minute = 0, second = 0; 

    char* s_num = NULL; 

     

    const char* pattern_date = "[0-9]{2,4}(-|/|年)[0-9]{1,2}(-|/|月)[0-9]{1,2}"; 

    const char* pattern_time = "[0-9]{1,2}:[0-9]{1,2}(:[0-9]{1,2})?"; 

    int z = 0; 

    regex_t reg_date, reg_time; 

    regmatch_t pm_date[1], pm_time[1]; 

     

    // 提取日期 

    regcomp(&reg_date, pattern_date, REG_EXTENDED); 

    z = regexec(&reg_date, str, 1, pm_date, 0); 

    regfree(&reg_date); 

    if(0 != z) 

    { 

        fprintf(stderr, " invalid date format: [%s]\n", str); 

        strcpy(datetime, "2000-01-01 00:00:00"); 

        return -1; 

    } 

    char* s_date = NULL; 

    return_if_fail(s_date = substr(str,  

        pm_date[0].rm_so,  

        pm_date[0].rm_eo - pm_date[0].rm_so), -1); 

    int n_offset = 1; 

    int date_l = 0; 

    int date_r = 0; 

    date_l = find(s_date, "-"); 

    date_r = rfind(s_date, "-"); 

    if(-1 == date_l) 

    { 

        date_l = find(s_date, "/"); 

    } 

    if(-1 == date_r || date_r == date_l) 

    { 

        date_r = rfind(s_date, "/"); 

    } 

    if(-1 == date_l) 

    { 

        date_l = find(s_date, "年"); 

        n_offset = strlen("年"); 

    } 

    if(-1 == date_r || date_r == date_l) 

    { 

        date_r = find(s_date, "月"); 

        n_offset = strlen("月"); 

    } 

    return_if_fail(s_num = substr(s_date, 0, date_l - 0), -1); 

    year = atoi(s_num); free(s_num); 

    if(year < 100) { year += 2000; }; 

    return_if_fail(s_num = substr(s_date, \ 

        date_l + n_offset, date_r - date_l - n_offset), -1); 

    month = atoi(s_num); free(s_num); 

    return_if_fail(s_num = substr(s_date,  

        date_r + n_offset, strlen(s_date) - date_r - n_offset), -1); 

    day = atoi(s_num); free(s_num); 

    free(s_date); 

     

    // 提取時間 

    regcomp(&reg_time, pattern_time, REG_EXTENDED); 

    z = regexec(&reg_time, str, 1, pm_time, 0); 

    regfree(&reg_time); 

    if(0 != z) 

    { 

        fprintf(stderr, " invalid time format: [%s]\n", str); 

        hour = 0; 

        minute = 0; 

        second = 0; 

        sprintf(datetime, "%04d-%02d-%02d %02d:%02d:%02d",  

            year, month, day, hour, minute, second); 

        return 0; 

    } 

    char* s_time = NULL; 

    return_if_fail(s_time = substr(str, \ 

        pm_time[0].rm_so, pm_time[0].rm_eo - pm_time[0].rm_so), -1); 

    int time_l = find(s_time, ":"); 

    int time_r = rfind(s_time, ":"); 

    return_if_fail(s_num = substr(s_time, 0, time_l - 0), -1); 

    hour = atoi(s_num); free(s_num); 

    if(time_l != time_r) 

    { 

        return_if_fail(s_num = substr(s_time, \ 

            time_l + 1, time_r - time_l - 1), -1); 

        minute = atoi(s_num); free(s_num); 

        return_if_fail(s_num = substr(s_time, \ 

            time_r + 1, strlen(s_time) - time_r - 1), -1); 

        second = atoi(s_num); free(s_num); 

    } 

    else 

    { 

        return_if_fail(s_num = substr(s_time, \ 

            time_l + 1, strlen(s_time) - time_l - 1), -1); 

        minute = atoi(s_num); free(s_num); 

        second = 0; 

    } 

    free(s_time); 

    sprintf(datetime, "%04d-%02d-%02d %02d:%02d:%02d",  

            year, month, day, hour, minute, second); 

    return 0; 

 

char* substr(const char* str, int pos, int len) 

    if(len <= 0) 

    { 

        printf("[*ERROR]: %s: %d: str = [%s], pos = [%d], len = [%d]\n", \ 

            __FILE__, __LINE__, str, pos, len); 

        return NULL; 

    } 

     

    char *sp = (char*) malloc(len + 1); 

    sp[len] = 0; 

     

    int i = 0; 

    for(; i < len; i++)  { 

        sp[i] = str[pos + i]; 

    } 

     

    return sp; 

 

int find(const char *src, const char *str) 

    int i = 0; 

    int j = 0; 

    int n_len_src = strlen(src); 

    int n_len_str = strlen(str); 

    int n_pos = 0; 

     

    for(i = 0 ; i <= n_len_src - n_len_str; i++) { 

        n_pos = i; 

        for(j = 0 ; j < n_len_str ; j++) { 

            if(*(src + n_pos) != *(str + j)) { 

                break; 

            } 

            if(j == n_len_str - 1) { 

                return i; 

            } 

            n_pos++; 

        } 

    } 

    return -1; 

 

int rfind(const char *src, const char *str) 

    int i = 0; 

    int j = 0; 

    int n_len_src = strlen(src); 

    int n_len_str = strlen(str); 

    int n_pos = 0; 

     

    for(i = n_len_src - n_len_str ; i > 0; i--) { 

        n_pos = i; 

        for(j = 0 ; j < n_len_str ; j++) { 

            if(*(src + n_pos) != *(str + j)) { 

                break; 

            } 

            if(j == n_len_str - 1) { 

                return i; 

            } 

            n_pos++; 

        } 

    } 

    return -1; 

 

 

 

測試示例test.c

 

/**

 * 編譯: gcc test.c PhoneDateExtract.c -o test

 * 執行: ./test

 * 結果: 

 *  format phone = [800-2142-325]

 *  format datetime = [2011-03-07 14:03:00]

 */ 

 

#include "PhoneDateExtract.h" 

#include <stdlib.h> 

#include <stdio.h> 

 

int main(int argc, char* argv[]) 

    // 中國大陸區域通用電話號碼提取 

    char* phone = NULL; 

    phone_extract("電話:800-2142-325", &phone); 

    printf("format phone = [%s]\n", phone); 

    free(phone); 

     

    // 簡體中文文本網頁時間提取 

    char* datetime = NULL; 

    datetime_extract("2011年3月7日 14:03", &datetime); 

    printf("format datetime = [%s]\n", datetime); 

    free(datetime); 

 

    return 0; 

 

資源下載:http://up.2cto.com/2011/1010/20111010103218741.zip

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved