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

来源:互联网 发布:淘宝测款 编辑:程序博客网 时间:2024/05/17 02:25

直接看代码:

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__



源文件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://download.csdn.net/detail/firstboy0513/3667780


原创粉丝点击