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

C++ 字符串模糊匹配:跨平台 fnmatch 實現(支持 * ? 通配符)

     編輯:C++ 入門

需求背景

配置授權字符串如 company|product|system,需支持通配符 * 匹配任意字符串,? 匹配單字符。Linux 有 fnmatch,Windows 無,需跨平台實現。

核心匹配邏輯:遞歸回溯

模式串 pattern、目標串 str,指針 p, s 分別掃描:

  • 字符相同或模式為 ?:雙指針前進。
  • 模式為 *:嘗試匹配 0~剩餘長度字符,遞歸檢查後續。
  • 否則匹配失敗。

Windows 版 SafeFNMatch

bool SafeFNMatch(const char* pattern, size_t patt_len,
                 const char* str, size_t str_len) {
    size_t p = 0, s = 0;
    while (true) {
        if (p == patt_len && s == str_len) return true;
        if (p == patt_len) return false;
        if (s == str_len)
            return (p+1 == patt_len && pattern[p] == '*'); // 尾部 * 可匹配空
        if (pattern[p] == str[s] || pattern[p] == '?') {
            p++; s++; continue;
        }
        if (pattern[p] == '*') {
            if (p+1 == patt_len) return true; // * 結尾匹配任意剩餘
            do {
                if (SafeFNMatch(pattern+p+1, patt_len-p-1, str+s, str_len-s))
                    return true;
                s++;
            } while (s != str_len);
            return false;
        }
        return false;
    }
}

跨平台封裝

#ifdef _WIN32
#define FNM_PATHNAME (1<<0)
#define FNM_NOESCAPE (1<<1)
#define FNM_PERIOD   (1<<2)
#define FNM_NOMATCH  1
#define fnmatch fnmatch_win

int fnmatch_win(const char* pattern, const char* name, int flags = 0) {
    return SafeFNMatch(pattern, strlen(pattern), name, strlen(name)) ? 0 : FNM_NOMATCH;
}
#else
#include 
#endif

測試用例

模式目標串結果
sina|*|pushersina|weibo|pusher匹配
*|*|pushersina|weibo|pusher匹配
sina|pic|*sina|weibo|pusher不匹配
*|*|signsina|weibo|pusher不匹配

關鍵點總結

  1. 遞歸回溯處理 *,雖然最壞指數級,但實際模式串短、* 少,極快。
  2. 跨平台宏隔離:Windows 用自實現,Linux 直接調用系統 fnmatch。
  3. 注意 FNM_PATHNAME 等標誌位在 Windows 版未實現,如需可擴展。
  4. 代碼源自 Google glog,經過實戰驗證。
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved