【问题标题】:Distance between regular expression正则表达式之间的距离
【发布时间】:2011-01-09 00:42:07
【问题描述】:

我们可以计算正则表达式之间的某种距离吗?

这个想法是衡量两个正则表达式的相似之处。

【问题讨论】:

  • 你想做什么?
  • 你如何测量那个距离?
  • @Gumbo:我想这是问题的一部分。

标签: regex comparison formal-languages


【解决方案1】:

您可以使用一些指标:

  1. 有效匹配的长度。一些正则表达式有固定的大小,一些有上限,一些有下限。比较它们的长度或可能的长度有多相似。

  2. 匹配的字符。任何正则表达式都会有一组匹配可以包含的字符(可能是所有字符)。比较包含的字符集。

  3. 使用一个大文档,看看每个正则表达式有多少匹配,其中有多少是相同的。

您在寻找严格等价吗?

【讨论】:

  • +1:我更喜欢这个答案而不是当前投票率最高的答案,因为您已经列出了一个非常实用的具体建议列表,这些建议很容易实施。
【解决方案2】:

我认为首先您需要自己了解如何看待两个表达式之间的“差异”。基本上,定义一个距离度量。

在一般情况下,制作起来会完全不同。根据您需要做什么,您可能会认为在某个地方允许一个不同的角色是一个很大的不同。在另一种情况下,允许任意数量的后续但相同的字符可能不会产生太大差异。

我还想强调,通常当他们谈论距离函数时,他们会将它们应用于...,好吧,我们称它们为标记。在我们的例子中,字符序列。您愿意做的是将这种方法应用到那些令牌上,而不是应用到规则上,大量的令牌将匹配。我不太确定这是否有意义。

不过,我相信我们可以想到一些东西,但不是一般的,而是针对一个特定且非常有限的情况。你有什么例子可以给我们看吗?

【讨论】:

    【解决方案3】:

    您可以为两个正则表达式构建deterministic finite-state machines 并比较转换。然后可以使用两个转换的差异来衡量这些正则表达式的距离。

    【讨论】:

    • 或许先一步,将状态机转化为图表示,寻找同构?
    • 你如何比较两个相当相似的正则表达式'\w+\d+'和'[a-zA-Z]{1,63}[1-9][0-9]{, 3}' 使用这种方法?如何判断不同 FSM 中的两个状态是“等价的”还是“相似的”?
    • @Noufal Ibrahim:是的,我的意思是这样的。还有一些算法可以判断两个有限状态机是否等价。
    • @Mark Byers:实际的问题是如何衡量相似度。 \w[a-zA-Z]+{1,63}\d[1-9] 以及 *{,3} 的相似度如何?
    • 是的,我知道很难衡量相似性,我只是不明白构建确定性状态机有什么帮助。 “两种转换的区别”是什么?您如何确定两个不同 FSM 中间的两个不同状态是否足够等效,以至于测量“它们的跃迁距离”是有意义的?您将如何定义 FSM 状态之间的映射?您能否扩展您的答案?虽然这个想法看起来很有趣,但我不明白这在实践中如何发挥作用。你知道这方面的真实例子吗?
    【解决方案4】:

    如果您有两个正则表达式并有一组示例输入,您可以尝试将每个输入与每个正则表达式进行匹配。对于每个输入:

    • 如果它们都匹配或都不匹配,则得分为 0。
    • 如果一个匹配而另一个不匹配,则得分 1。

    将此分数与所有输入相加,这将为您提供正则表达式之间的“距离”。这将使您了解两个正则表达式对于典型输入的不同频率。如果您的样本输入集很大,计算将非常缓慢。如果两个正则表达式都无法匹配几乎所有随机字符串并且您的预期输入完全是随机的,则它根本不起作用。例如,如果在随机输入上进行测试,正则表达式 'sgjlkwren' 和正则表达式 'ueuenwbkaalf' 可能都不会匹配任何东西,所以这个指标会说它们之间的距离为零。这可能是也可能不是您想要的(可能不是)。

    您也许可以分析正则表达式的结构并使用有偏随机抽样来故意命中匹配频率高于完全随机输入的字符串。例如,如果两个正则表达式都要求字符串以 'foo' 开头,您可以确保您的测试输入也始终以 foo 开头,以避免浪费时间来测试您知道两者都会失败的字符串。

    因此,总而言之:除非您遇到非常特殊的情况,即输入集受限和/或正则表达式语言受限,否则我认为这是不可能的。如果您对输入和正则表达式确实有一些限制,那么它可能是可能的。请说明这些限制是什么,也许我可以想出更好的办法。

    【讨论】:

      【解决方案5】:

      我想你可以在实际的正则表达式字符串之间计算一个Levenshtein Distance。这当然是衡量两个不同正则表达式字符串之间“距离”的一种方法。

      当然,我认为这里可能根本不需要正则表达式,并且计算正则表达式将应用于的实际“值”字符串的 Levenshtein 距离可能会产生更好的结果。

      【讨论】:

      • 请注意,正则表达式的距离度量与字符串的距离度量完全不同。例如。 distance(regex("a|b"), regex("b|a") 定义为 0。有些变化比其他变化更重要。 abcde 可能类似于bacde,只是交换了两个字符,但^[0-9] 完全不同于[^0-9]
      【解决方案6】:

      在 SO:Generating strings from regexes 的早期问题中隐藏了一个答案。您可以通过使用一个正则表达式生成字符串并检查其中有多少与另一个正则表达式匹配来计算(不对称)距离度量。

      这可以通过去除共享的前缀/后缀来优化。例如。 a[0-9]*a[0-7]* 共享 a 前缀,因此您可以计算 [0-9]*[0-7]* 之间的距离。

      【讨论】:

        猜你喜欢
        • 2015-07-09
        • 1970-01-01
        • 2012-04-22
        • 1970-01-01
        • 2014-01-12
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-11-18
        相关资源
        最近更新 更多