首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> C語言 >> 關於C語言

C 語言正則表達式實戰:電話號碼與日期時間提取完整解決方案

     編輯:關於C語言

專案架構:POSIX Regex API

  • <regex.h>:標準 C 正則庫(POSIX.2),支援擴展正則語法(ERE)
  • 核心函數:regcomp 編譯、regexec 匹配、regfree 釋放
  • 匹配結果:regmatch_t 陣列記錄捕獲組起止位置 rm_so/rm_eo

電話號碼提取:中國大陸通用規則

正則模式設計


// 擴展正則語法(ERE)
(([0-9]{11})|((400|800)([0-9\\-]{7,10})|(([0-9]{4}|[0-9]{3})(-| )?)?([0-9]{7,8})((-| |轉)*([0-9]{1,4}))?))

涵蓋類型

類型模式片段範例
手機號[0-9]{11}13812345678
400/800 號(400|800)([0-9\\-]{7,10})400-800-1234、8001234567
固話(含區號、分機)(([0-9]{4}|[0-9]{3})(-| )?)?([0-9]{7,8})((-| |轉)*([0-9]{1,4}))?010-12345678、021 87654321 轉 801

日期時間提取:中文格式標準化

兩階段匹配策略

  1. 日期:[0-9]{2,4}(-|/|年)[0-9]{1,2}(-|/|月)[0-9]{1,2}
  2. 時間:[0-9]{1,2}:[0-9]{1,2}(:[0-9]{1,2})?

解析邏輯:分隔符自適應 + 統一格式化輸出

  • 檢測分隔符:-、/、年/月
  • 提取年/月/日,兩位數年份自動補 2000+
  • 提取時/分/秒,秒可選預設 0
  • 統一輸出:YYYY-MM-DD HH:MM:SS

核心工具函數


// 子串提取:[pos, pos+len)
char* substr(const char* str, int pos, int len) {
    char* sp = malloc(len + 1);
    for (int i = 0; i < len; ++i) sp[i] = str[pos + i];
    sp[len] = '\0';
    return sp;
}

// 正向查找子串位置
int find(const char* src, const char* target) { /* 朴素 O(nm) 實現 */ }

// 反向查找子串位置
int rfind(const char* src, const char* target) { /* 從右向左 */ }

完整 API 介面


// phone_extract.h
int phone_extract(const char* str, char** phone);      // 返回 0 成功,*phone 需 free()
int datetime_extract(const char* str, char** datetime); // 返回 0 成功,格式 YYYY-MM-DD HH:MM:SS

使用範例


#include "PhoneDateExtract.h"
#include <stdio.h>
#include <stdlib.h>

int main() {
    char* phone = NULL;
    phone_extract("電話:800-2142-325", &phone);
    printf("phone = [%s]\n", phone); // [800-2142-325]
    free(phone);

    char* dt = NULL;
    datetime_extract("2011年3月7日 14:03", &dt);
    printf("datetime = [%s]\n", dt); // [2011-03-07 14:03:00]
    free(dt);
    return 0;
}

編譯與鏈接


gcc test.c PhoneDateExtract.c -o test -lregex
# 某些系統需顯式鏈接 -lregex

關鍵技術點與避坑指南

  1. ERE vs BRE:regcomp(..., REG_EXTENDED) 啟用擴展正則(支援 {m,n}、|、() 等),否則為基本正則(需轉義)。
  2. 記憶體管理:regmatch_t 給出位置,必須手動 substr 複製並 free;輸出緩衝區同樣需調用方 free。
  3. 匹配貪婪性:POSIX 正則預設貪婪(最長匹配),[0-9]* 會吃盡可能多數字。
  4. 中文字元處理:正則按位元組匹配,UTF-8 下 年 佔 3 字節,模式中直接寫 年 需原始碼編碼一致,或用十六進制 \\xE5\\xB9\\xB4。
  5. 效能考量:頻繁調用請緩存 regex_t 編譯結果,避免重複 regcomp。
  6. 錯誤處理:regcomp/regexec 非零返回碼需用 regerror 獲取錯誤訊息。

擴展方向

  • 支援更多電話格式:國際碼 +86、括號區號 (010)
  • 日期支援相對時間:今天、明天、下週一
  • 引入 PCRE2 庫:支援 Perl 相容正則(非貪婪 .*?、前瞻/後顧、遞歸),功能更強
  • 封裝為 C++ 類:RAII 管理 regex_t,提供流式介面
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved