用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》中介绍的正则表达式引擎设计,是一个非常精简但完整的实现。

相关推荐
wuminyu6 小时前
ForkJoinPool窃取线程在扫描其他WorkQueue时的随机采样算法与Phase线程挂起唤醒机制解析
java·linux·c语言·jvm·c++
半亩码田7 小时前
C#转Python第4.8篇:正则表达式:Python re 模块 vs C# System.Text.RegularExpressions
python·正则表达式·c#
Logic1017 小时前
C语言/数据结构欧几里得算法题解:长方形切割最大正方形——贪心划分计数
c语言·数据结构·算法·贪心算法·时间复杂度·空间复杂度·欧几里得算法
北京盛世宏博7 小时前
工业环境监测选型:Modbus TCP以太网温湿度传感器部署、调试、避坑全指南
开发语言·网络·php
4SAPI8 小时前
AI API Gateway平台哪个好?从架构视角看企业多模型网关选型与实践
java·大数据·人工智能·gateway·php
ly76898 小时前
MongoDB 副本集选举风暴排查:从心跳超时到 Journal 刷盘阻塞
数据库·mongodb·php·mongodb 副本集·选举风暴·journal 刷盘·writeconcern
源图客8 小时前
浏览器开发者工具使用
开发语言·php
qetfw9 小时前
Debian iptables 防火墙:默认拒绝、SNAT 与 DNAT 验证
linux·服务器·debian·php
老王爱玩车9 小时前
文件操作从打开到缓冲区
c语言·开发语言·学习
Zwawa10 小时前
传感器模块都在交出什么:从模拟电压到数字协议
c语言·单片机·嵌入式