用C实现一个最简单的正则表达式引擎

用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;
}

实现解析

  1. 核心函数

    • regex_match(): 入口函数,处理 ^ 开头的情况
    • match_here(): 在当前位置尝试匹配
    • match_star(): 专门处理 * 量词匹配
  2. 匹配逻辑

    • 普通字符:必须精确匹配
    • .:匹配任意单个字符
    • *:匹配前导字符零次或多次(贪婪匹配)
    • ^:必须从字符串开头匹配
    • $:必须匹配到字符串结尾
  3. 递归实现

    • 通过递归调用实现模式匹配
    • 遇到 * 时尝试所有可能的匹配长度

扩展建议

这个简单引擎可以进一步扩展:

  1. 添加 +(一次或多次)和 ?(零次或一次)量词
  2. 支持字符类 [a-z]
  3. 实现转义字符 \
  4. 添加分组捕获功能

这个实现参考了Rob Pike在《The Practice of Programming》中介绍的正则表达式引擎设计,是一个非常精简但完整的实现。

相关推荐
JaguarJack17 小时前
FrankenPHP 原生支持 Windows 了
后端·php·服务端
BingoGo17 小时前
FrankenPHP 原生支持 Windows 了
后端·php
JaguarJack2 天前
PHP 的异步编程 该怎么选择
后端·php·服务端
BingoGo2 天前
PHP 的异步编程 该怎么选择
后端·php
JaguarJack2 天前
为什么 PHP 闭包要加 static?
后端·php·服务端
雨中飘荡的记忆3 天前
正则表达式入门到实战
正则表达式
ServBay3 天前
垃圾堆里编码?真的不要怪 PHP 不行
后端·php
用户962377954483 天前
CTF 伪协议
php
RuoZoe4 天前
重塑WPF辉煌?基于DirectX 12的现代.NET UI框架Jalium
c语言
BingoGo6 天前
当你的 PHP 应用的 API 没有限流时会发生什么?
后端·php