直接看代碼:
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(®_date, pattern_date, REG_EXTENDED);
z = regexec(®_date, str, 1, pm_date, 0);
regfree(®_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(®_date, pattern_date, REG_EXTENDED);
z = regexec(®_date, str, 1, pm_date, 0);
regfree(®_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(®_time, pattern_time, REG_EXTENDED);
z = regexec(®_time, str, 1, pm_time, 0);
regfree(®_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