配置授權字符串如 company|product|system,需支持通配符 * 匹配任意字符串,? 匹配單字符。Linux 有 fnmatch,Windows 無,需跨平台實現。
模式串 pattern、目標串 str,指針 p, s 分別掃描:
?:雙指針前進。*:嘗試匹配 0~剩餘長度字符,遞歸檢查後續。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|*|pusher | sina|weibo|pusher | 匹配 |
*|*|pusher | sina|weibo|pusher | 匹配 |
sina|pic|* | sina|weibo|pusher | 不匹配 |
*|*|sign | sina|weibo|pusher | 不匹配 |
*,雖然最壞指數級,但實際模式串短、* 少,極快。fnmatch。FNM_PATHNAME 等標誌位在 Windows 版未實現,如需可擴展。