用C实现一个简单的正则表达式引擎
下面我将实现一个极简的正则表达式引擎,仅支持以下基本功能:
.
匹配任意单个字符*
匹配零个或多个前导字符^
匹配字符串开头$
匹配字符串结尾
完整代码实现
c
#include <stdio.h>
#include <stdbool.h>
bool match_here(const char *regexp, const char *text);
bool match_star(char c, const char *regexp, const char *text);
/* 正则表达式匹配入口函数 */
bool regex_match(const char *regexp, const char *text) {
// 处理 ^ 开头的情况
if (regexp[0] == '^') {
return match_here(regexp + 1, text);
}
// 尝试在文本的每个位置匹配
do {
if (match_here(regexp, text)) {
return true;
}
} while (*text++ != '\0');
return false;
}
/* 在当前位置尝试匹配 */
bool match_here(const char *regexp, const char *text) {
// 正则表达式已结束,匹配成功
if (regexp[0] == '\0') {
return true;
}
// 处理 $ 结尾的情况
if (regexp[0] == '$' && regexp[1] == '\0') {
return *text == '\0';
}
// 处理 * 量词
if (regexp[1] == '*') {
return match_star(regexp[0], regexp + 2, text);
}
// 处理 . 通配符或普通字符匹配
if (*text != '\0' && (regexp[0] == '.' || regexp[0] == *text)) {
return match_here(regexp + 1, text + 1);
}
return false;
}
/* 处理 * 量词匹配 */
bool match_star(char c, const char *regexp, const char *text) {
do {
// 尝试匹配剩余部分
if (match_here(regexp, text)) {
return true;
}
} while (*text != '\0' && (*text++ == c || c == '.'));
return false;
}
/* 测试函数 */
int main() {
const char *tests[][2] = {
{"a", "a"}, // 匹配
{"a", "b"}, // 不匹配
{"a*", ""}, // 匹配
{"a*", "aaaaa"}, // 匹配
{".*", "anything"}, // 匹配
{"^a", "a"}, // 匹配
{"^a", "ba"}, // 不匹配
{"a$", "a"}, // 匹配
{"a$", "ab"}, // 不匹配
{"a*b", "aaaab"}, // 匹配
{"a*b", "b"}, // 匹配
{"a*b", "aaaac"}, // 不匹配
{NULL, NULL}
};
for (int i = 0; tests[i][0] != NULL; i++) {
bool result = regex_match(tests[i][0], tests[i][1]);
printf("'%s' matches '%s': %s\n",
tests[i][0], tests[i][1], result ? "true" : "false");
}
return 0;
}
实现解析
-
核心函数:
regex_match()
: 入口函数,处理^
开头的情况match_here()
: 在当前位置尝试匹配match_star()
: 专门处理*
量词匹配
-
匹配逻辑:
- 普通字符:必须精确匹配
.
:匹配任意单个字符*
:匹配前导字符零次或多次(贪婪匹配)^
:必须从字符串开头匹配$
:必须匹配到字符串结尾
-
递归实现:
- 通过递归调用实现模式匹配
- 遇到
*
时尝试所有可能的匹配长度
扩展建议
这个简单引擎可以进一步扩展:
- 添加
+
(一次或多次)和?
(零次或一次)量词 - 支持字符类
[a-z]
- 实现转义字符
\
- 添加分组捕获功能
这个实现参考了Rob Pike在《The Practice of Programming》中介绍的正则表达式引擎设计,是一个非常精简但完整的实现。