【发布时间】:2011-01-09 00:42:07
【问题描述】:
我们可以计算正则表达式之间的某种距离吗?
这个想法是衡量两个正则表达式的相似之处。
【问题讨论】:
-
你想做什么?
-
你如何测量那个距离?
-
@Gumbo:我想这是问题的一部分。
标签: regex comparison formal-languages
我们可以计算正则表达式之间的某种距离吗?
这个想法是衡量两个正则表达式的相似之处。
【问题讨论】:
标签: regex comparison formal-languages
您可以使用一些指标:
有效匹配的长度。一些正则表达式有固定的大小,一些有上限,一些有下限。比较它们的长度或可能的长度有多相似。
匹配的字符。任何正则表达式都会有一组匹配可以包含的字符(可能是所有字符)。比较包含的字符集。
使用一个大文档,看看每个正则表达式有多少匹配,其中有多少是相同的。
您在寻找严格等价吗?
【讨论】:
我认为首先您需要自己了解如何看待两个表达式之间的“差异”。基本上,定义一个距离度量。
在一般情况下,制作起来会完全不同。根据您需要做什么,您可能会认为在某个地方允许一个不同的角色是一个很大的不同。在另一种情况下,允许任意数量的后续但相同的字符可能不会产生太大差异。
我还想强调,通常当他们谈论距离函数时,他们会将它们应用于...,好吧,我们称它们为标记。在我们的例子中,字符序列。您愿意做的是将这种方法应用到那些令牌上,而不是应用到规则上,大量的令牌将匹配。我不太确定这是否有意义。
不过,我相信我们可以想到一些东西,但不是一般的,而是针对一个特定且非常有限的情况。你有什么例子可以给我们看吗?
【讨论】:
您可以为两个正则表达式构建deterministic finite-state machines 并比较转换。然后可以使用两个转换的差异来衡量这些正则表达式的距离。
【讨论】:
\w 与 [a-zA-Z]、+ 与 {1,63}、\d 与 [1-9] 以及 * 与 {,3} 的相似度如何?
如果您有两个正则表达式并有一组示例输入,您可以尝试将每个输入与每个正则表达式进行匹配。对于每个输入:
将此分数与所有输入相加,这将为您提供正则表达式之间的“距离”。这将使您了解两个正则表达式对于典型输入的不同频率。如果您的样本输入集很大,计算将非常缓慢。如果两个正则表达式都无法匹配几乎所有随机字符串并且您的预期输入完全是随机的,则它根本不起作用。例如,如果在随机输入上进行测试,正则表达式 'sgjlkwren' 和正则表达式 'ueuenwbkaalf' 可能都不会匹配任何东西,所以这个指标会说它们之间的距离为零。这可能是也可能不是您想要的(可能不是)。
您也许可以分析正则表达式的结构并使用有偏随机抽样来故意命中匹配频率高于完全随机输入的字符串。例如,如果两个正则表达式都要求字符串以 'foo' 开头,您可以确保您的测试输入也始终以 foo 开头,以避免浪费时间来测试您知道两者都会失败的字符串。
因此,总而言之:除非您遇到非常特殊的情况,即输入集受限和/或正则表达式语言受限,否则我认为这是不可能的。如果您对输入和正则表达式确实有一些限制,那么它可能是可能的。请说明这些限制是什么,也许我可以想出更好的办法。
【讨论】:
我想你可以在实际的正则表达式字符串之间计算一个Levenshtein Distance。这当然是衡量两个不同正则表达式字符串之间“距离”的一种方法。
当然,我认为这里可能根本不需要正则表达式,并且计算正则表达式将应用于的实际“值”字符串的 Levenshtein 距离可能会产生更好的结果。
【讨论】:
distance(regex("a|b"), regex("b|a") 定义为 0。有些变化比其他变化更重要。 abcde 可能类似于bacde,只是交换了两个字符,但^[0-9] 完全不同于[^0-9]
在 SO:Generating strings from regexes 的早期问题中隐藏了一个答案。您可以通过使用一个正则表达式生成字符串并检查其中有多少与另一个正则表达式匹配来计算(不对称)距离度量。
这可以通过去除共享的前缀/后缀来优化。例如。 a[0-9]* 和 a[0-7]* 共享 a 前缀,因此您可以计算 [0-9]* 和 [0-7]* 之间的距离。
【讨论】: