【问题标题】:Recommendations for a C implementation of a regex parser正则表达式解析器的 C 实现建议
【发布时间】:2010-12-10 14:09:09
【问题描述】:

我正在考虑在我正在开发的 C 库中实现正则表达式解析器。现在,问题是:有没有我可以逐字使用或尽可能少改动的开源代码?我对代码的期望是:

  • 需要用 C(不是 C++)编写
  • 需要在gcc、mingw、M$VC下编译
  • 它不得依赖于任何第三方或特定于操作系统的头文件/库(即,编译它所需的一切都必须通过 gcc、mingw、M$VC 的基本安装随时可用
  • 如果它使用与 Perl 兼容的正则表达式语法(如 PHP 中的 PCRE)会很好。
  • 理想情况下,代码应该尽可能紧凑

您有什么现成的解决方案可以推荐吗?我正在研究 C 的 PCRE,它看起来拥有 PHP 中可用的所有内容(哪些规则),但大小(1.4MB DL)有点吓人。你认为这是一个可靠的赌注吗?还是有其他值得考虑的选择?

[编辑]

我正在开发的库是开源的,BSD 许可证。

【问题讨论】:

  • 您将根据什么许可证发布您的库?
  • PHP 是建立在 C 之上的。如果 PHP 将 PCRE 用于 C,我不会感到惊讶。
  • @Jefromi:感谢您的询问,我忘了添加那条信息。我已经更新了问题。
  • @Benedict:我相信确实如此:php.net/manual/en/book.pcre.php :)
  • 百万美元?严重地?这曾经很酷,就像十年前一样。

标签: c regex parsing recommendation-engine


【解决方案1】:

PCRE 如此之大是因为正则表达式困难。无论如何,其中大部分是文档和支持代码;当编译成目标代码时,它要小得多。

【讨论】:

  • 正则表达式并不难; PCRE 只是臃肿,最后我检查它是O(2^n)。一个完整的 POSIX 正则表达式实现应该小于 10k(x86 机器代码);我不确定 Perl 风格的正则表达式(它甚至不是一种常规语言),因为它有各种奇怪的扩展,但我严重怀疑 PCRE 有这么大的正当理由。
  • PCRE 为 O(2^n) 的原因是因为它支持 perl 风格的正则表达式(支持反向引用)。你写过回溯正则表达式实现吗?你是谁说它不难或它应该有多大?
  • 显然有反向引用它是O(2^n),但最后我检查它也有非常糟糕的渐近行为(也许只是O(n^2)O(nm))对于许多纯粹的常规,非反向-包含引用的表达式。
  • 至于应该有多大,我看了一下TRE(虽然它使用渐近高效的算法,但代码相当臃肿),看到相关.o的总数为size(1)文件大约19k。之前详细阅读了代码后,我很快估计您可以减少大约一半的代码大小并同时提高性能(其中大部分是通过简化数据结构和提前将故障案例隔离到单次检查)。这就是我的 10k 估计值的来源。
  • TRE 说它有 O(nm^2)。突然间 O(nm) 听起来并不那么糟糕。我承认 TRE 的案例非常有说服力,但我不认为 PCRE 是一个糟糕的选择。
【解决方案2】:

RE2,Google 正则表达式实现在线性时间内进行匹配(O(n) 如果n 是字符串的长度),PCRE 和大多数其他正则表达式引擎在最坏的情况下以指数时间运行。另一个值得注意的O(n) 正则表达式匹配器是flex,但它在编译时需要所有可能的正则表达式。如果您正在寻找比 PCRE 更小的东西,请查看 busybox 中的正则表达式匹配器,或 lua 中的模式匹配器。

【讨论】:

  • @mingos,即使胆量是用 C++ 编写的,你能不能不包装它以供 C 代码使用?毕竟,您命名的所有编译器都使 C++ 可用。
  • 并非如此。有问题的图书馆不是我的财产,我只是一个共同维护者。该策略相当严格:所有代码都用 C 编写,然后在其上添加 C++ 包装器。我真的没有能力影响它。
【解决方案3】:

如果您对 POSIX 正则表达式语法感到满意,可以尝试 TRE。如果你想要 Perl 语法,Google 有一个值得一试的新实现。

【讨论】:

    【解决方案4】:

    PCRE 几乎是正则表达式实现的事实标准(有充分的理由)。不要担心大小,它很大,因为正则表达式实现很复杂。随便用吧。

    【讨论】:

    • 推荐糟糕的代码,因为它是“事实上的标准”并且因为 foo 是“复杂的”(提示:它不是)不是好的建议。
    • 我不推荐它,因为它很复杂。我说PCRE“几乎是事实上的标准”。我不认为这是糟糕的代码。
    猜你喜欢
    • 2011-05-11
    • 2011-05-11
    • 1970-01-01
    • 1970-01-01
    • 2018-02-06
    • 2011-07-20
    • 2012-06-15
    • 1970-01-01
    相关资源
    最近更新 更多