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

GNU C 庫 POSIX 正則表達式 API 使用詳解

     編輯:關於C語言

POSIX 正則表達式概述

GNU C 庫 (glibc) 提供 POSIX.2 標準的正則表達式接口,風格與 Perl/PCRE 不同,屬於**擴展正則表達式 (ERE)** 方言。頭文件 <regex.h>。

核心數據結構與函數

typedef struct {
    regoff_t rm_so; // 匹配起始偏移
    regoff_t rm_eo; // 匹配結束偏移 (不包含)
} regmatch_t;

int regcomp(regex_t *preg, const char *pattern, int cflags);
int regexec(const regex_t *preg, const char *string, size_t nmatch, regmatch_t pmatch[], int eflags);
void regfree(regex_t *preg);

編譯標志 cflags

標志含義
REG_EXTENDED使用擴展正則語法 (ERE),而非基本正則 (BRE)。**強烈建議始終開啟**。
REG_ICASE忽略大小寫匹配。
REG_NOSUB不記錄子表達式匹配位置,僅返回成功/失敗,加快速度。
REG_NEWLINE. 不匹配換行符,^/$ 匹配行首/行尾(而非整串首尾)。

執行標志 eflags

標志含義
REG_NOTBOL^ 不匹配字符串開頭(視為行中間)。
REG_NOTEOL$ 不匹配字符串結尾。

完整使用流程示例

#include <stdio.h>
#include <regex.h>
#include <string.h>

int main() {
    const char *pattern = "abc([0-9]+)"; // 捕獲組:數字序列
    const char *input = "Abc1234";
    regex_t regex;
    regmatch_t matches[3]; // [0]整體匹配, [1]第一個捕獲組
    int ret;

    // 1. 編譯正則
    ret = regcomp(®ex, pattern, REG_EXTENDED | REG_ICASE);
    if (ret != 0) {
        char errbuf[100];
        regerror(ret, ®ex, errbuf, sizeof(errbuf));
        fprintf(stderr, "編譯失敗: %s\n", errbuf);
        return 1;
    }

    // 2. 執行匹配
    ret = regexec(®ex, input, 3, matches, 0);
    if (ret == REG_NOMATCH) {
        printf("不匹配\n");
    } else if (ret == 0) {
        // 3. 提取匹配子串
        char buf[100];
        // 整體匹配
        snprintf(buf, sizeof(buf), "%.*s", 
                 (int)(matches[0].rm_eo - matches[0].rm_so), 
                 input + matches[0].rm_so);
        printf("整體匹配: [%s]\n", buf);
        // 第一個捕獲組
        snprintf(buf, sizeof(buf), "%.*s",
                 (int)(matches[1].rm_eo - matches[1].rm_so),
                 input + matches[1].rm_so);
        printf("捕獲組1: [%s]\n", buf);
    } else {
        fprintf(stderr, "匹配錯誤: %d\n", ret);
    }

    // 4. 釋放資源
    regfree(®ex);
    return 0;
}
/* 輸出:
整體匹配: [Abc1234]
捕獲組1: [1234]
*/

關鍵注意事項

  • 線程安全:regex_t 編譯後為只讀,可多線程共享 regexec;但 regcomp/regfree 非線程安全。
  • 性能:POSIX 正則引擎為 NFA 回溯實現,複雜模式(如嵌套量詞)易發生災難性回溯。高性能場景建議使用 **PCRE2** 或 **RE2** 庫。
  • 錯誤處理:regcomp 失敗需調用 regerror 獲取可讀信息。
  • 內存管理:regmatch_t 數組由調用者分配,大小至少為捕獲組數 + 1。
  • 字符編碼:POSIX 正則按字節處理,UTF-8 多字節字符可能被拆分匹配,需謹慎使用 . 和字符類。

POSIX ERE vs Perl/PCRE 語法差異速查

特性POSIX EREPerl/PCRE
捕獲組(...)(...)
非捕獲組不支持(?:...)
前瞻/後顧不支持(?=...) (?!...)
貪婪/懶惰量詞僅貪婪 * + ? {m,n}*? +? ?? {m,n}?
反向引用\1-\code{\9}\1-\code{\9、\g{10}
字符類簡寫[:digit:] 等 POSIX 類\d \w \s 等
單詞邊界不支持\b \B

替代方案推薦

  • PCRE2:Perl 兼容、功能最全、廣泛使用(PHP、R、Apache、Nginx)。
  • RE2:Google 開發、保證線性時間、無回溯風險、適合高併發服務。
  • C++11 <regex>:標準庫封裝,默認 ECMAScript 語法,也支持 std::regex_constants::extended (POSIX ERE)。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved