基于 DFA 的 Java 正则表达式引擎与 Capture

Posted

技术标签:

【中文标题】基于 DFA 的 Java 正则表达式引擎与 Capture【英文标题】:DFA Based Regular Expression Engines for Java with Capture 【发布时间】:2010-12-30 03:44:40 【问题描述】:

是否有任何(免费的)Java 正则表达式引擎,可以将正则表达式编译为 DFA,并在匹配 DFA 的同时进行组捕获?

我找到了 dk.brics.automaton 和 jrexx,它们都可以编译为 DFA,但似乎都无法进行组捕获。虽然我发现的其他引擎似乎可以编译为 NFA。

【问题讨论】:

用于性能优化。 我之所以问,是因为通常这些性能优势源于 DFA 引擎无法回溯。如果是这种情况,也许您可​​以使用原子分组/占有量词来实现相同的目的。也许您可以发布一些您想要实现的示例? 一些示例怎么样,我们可以看看您的问题是否可以以不同的方式解决 - 因为似乎没有人知道具有组捕获的 Java DFA 正则表达式引擎......如果它真的是 一个问题而不是过早的优化:) 感谢您的关注,但确实没有需要以不同方式解决的问题。我只是想看看基于 DFA 的引擎会对我的应用程序产生什么性能影响。 如果 NFA 不使用回溯,则 DFA 和 NFA 引擎之间不应该有任何明显的区别。如果你找到一个好的线性时空 NFA 引擎,你应该使用它。在没有组的情况下,即使是简单的实现仍然是恒定空间/线性时间。 【参考方案1】:

试试这个(可能不是 DFA,但比 java.util 快)http://jregex.sourceforge.net/gstarted-advanced.html#ngroups,或者这个:http://userguide.icu-project.org

根据该测试:http://tusker.org/regex/regex_benchmark.html,两者都很快(我们都知道基准测试只测试基准测试的创建者想要测试的内容)。

当我需要非常快速的 DFA 正则表达式时,我生​​成了一个使用 grep 的进程;-)(对于 6GB 的日志文件,它将我的时间从 10 分钟缩短到了几秒钟)。

【讨论】:

我怀疑它是否比 java.util.regex 快。这些小库来来去去,java.util.regex 年复一年地得到优化。如果你没有使用更好的算法,java.util.regex 最终会打败你。请参阅我对正则表达式引擎的回答,该引擎与 java.util.regex 完全不同,基于 DFA,因此速度更快。【参考方案2】:

我最近写了一个:tree-regex。

【讨论】:

【参考方案3】:

对于 C,有 TRE 和 Google 的 RE2 库。 TRE 使用 DFA,RE2 使用 NFA(据我所知),两者都可以分组匹配。但是我没有看到这样的 Java 库。

【讨论】:

RE2 实际上非常快。当人们要求正则表达式和速度时,值得指出它。 你搞错了。 TRE 使用 NFA,RE2 使用 NFA 和 DFA。具体来说,如果最多有一个捕获组,RE2 使用 DFA,否则使用 NFA。【参考方案4】:

你可以试试 Pat 正则表达式库@http://www.javaregex.com/。

【讨论】:

从网站上看,至少一点也不明显,这个引擎是基于 DFA 的,也不支持组捕获。如果是,并且确实如此,请您确认一下。 那个 lib (Stevesoft Pat) 确实支持捕获组,但它绝对不是基于 DFA。【参考方案5】:

dk.brics.automaton 是 DFA 似乎确实可以捕获组。我希望这个功能在这个问题之后的两年内是新的。查看 AutomatonMatcher 类。

见http://www.brics.dk/automaton/doc/dk/brics/automaton/AutomatonMatcher.html#group(int)

【讨论】:

它实际上不支持组匹配。 更新了组捕获 API 的链接 是的,但是您阅读了那个链接吗? “不支持捕获组,唯一有效的组是 0(整个匹配)。”

以上是关于基于 DFA 的 Java 正则表达式引擎与 Capture的主要内容,如果未能解决你的问题,请参考以下文章

使用基于 DFA(线性时间)的正则表达式捕获组:可能吗?

DFA和NFA的区别

正则表达式之原理篇

正则表达式

从正则表达式到 NFA 到 DFA 到最简 DFA (结束)

实现词法分析器时的 DFA 与正则表达式?