【问题标题】:check if two regexes match the same strings in java检查两个正则表达式是否匹配java中的相同字符串
【发布时间】:2012-01-05 09:40:01
【问题描述】:

我有两个正则表达式(简单示例:“[0-9]+”和“[0123456789]+”)。我想看看它们是否完全匹配相同的输入。是否有用于在 java 中进行此检查的内置函数?如果没有,是否有相对简单的算法来进行检查?谢谢!

【问题讨论】:

  • 我认为在 Java 中没有内置的方法可以做到这一点。就算法而言,“最简单”(就解释而言)是为每个正则表达式构建 DFA,在两者上运行 DFA 最小化算法,然后比较结果。
  • 这实际上是一个非常重要的问题,特别是因为 Java 正则表达式在最严格的意义上并不是“正则”。我认为您不会找到任何简单的方法来做到这一点。
  • 你想检查现代正则表达式(支持环视、反向引用和喜欢)吗?还是它们是“真实的”正则表达式(例如您发布的简单示例)?如果是第一个,我认为没有相对简单的解决方案(如果有解决方案的话!)。
  • 我不认为有一种方法可以通用地证明两个正则表达式即使在数学上也是相同的。你甚至无法证明表达式会停止。 en.wikipedia.org/wiki/Halting_problem
  • 虽然,如果你真的想要一个答案,你可以猜测和检查 :) 只需向他们扔大量随机字符串;扔得越多,两个表达式相等的可能性就越大。

标签: java regex state-machine dfa


【解决方案1】:

实际上有一种算法方法可以检查正则表达式是否相等,尽管它很复杂。方法如下:

  1. 将两个正则表达式转换为等效的 NFA。这是well-known and defined process.
  2. 通过powerset construction. 将两个 NFA 转换为 DFA
  3. 鉴于 DFA 的交集和互补是 closed and well defined,请构建两个 DFA 的 XOR。 (这有点滥用符号,但如果自动机是 A 和 B,则构造 AB'+A'B)
  4. 这个结果机器表示原始正则表达式之间的差异(一个中的任何字符串,但不是另一个)。现在只需从 DFA 的开始到结束运行 graph reachability。如果失败,它们是平等的,成功时,不相等!

【讨论】:

    【解决方案2】:

    首先,完全一样。其次,我无法想象内置功能可以满足您的需求。想一想:您实际上希望将正则表达式与多个输入进行匹配。什么输入?随机字符串?在这种情况下,您的随机字符串仅包含数字的机会是非常规律的。

    我可以稍微改变一下你的问题。这是我的版本。

    *我有 2 个正则表达式,并想验证它们的功能是否相同。 *

    这个问题很有道理。在这种情况下,我可以使用一个流行的单元测试框架(例如 JUnit 或 TestNG)编写一系列单元测试,并对这两个正则表达式运行相同的测试。我每次都期待相同的结果。但我必须自己写字符串。例如

    • 空字符串
    • 只有字母的字符串
    • 只有数字的字符串
    • 带有特殊字符的字符串
    • 带有 unicode 字符的字符串
    • 以前的混合

    等等等等

    【讨论】:

    • 嘿,这就是我在上一条评论中想要的(关于使用随机字符串)。除了,而不是单元测试框架,您可能应该使用 QuickCheck 之类的东西。无论如何,您应该使用 QuickCheck,但我离题了。
    • 我更喜欢一种方法来检查正则表达式的等价性,而不用在输入上测试它们。这仅仅是因为有太多可能的输入——事实上,可能的输入实际上是无限的。
    • 正则表达式不像数学公式:你不能导出它们并证明它们的等价性。它们是算法,因此不太可能以相同的方式编译,除非它像[[:digit:]] === \d 这样绝对微不足道。
    猜你喜欢
    • 1970-01-01
    • 2022-01-18
    • 1970-01-01
    • 2022-11-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多