如何检查正则表达式的相关性?

时间:2009-07-14 20:37:41

标签: regex relevance

假设我们有两个正则表达式:

1234.*

.*

输入:

1234567

显然他们都匹配,但是1234. *匹配得更好,因为它更具体。即更相关。有没有一种标准的检查方法哪种更相关?

编辑:

一些澄清。我想通过检查哪个正则表达式与输入最佳匹配来做出决定。在这种情况下,我只匹配数字。

电话号码示例:

输入:

31882481337

我们对以下每个regexp都有一条规则:

31.*
.*

在这种情况下,我希望使用绑定到31. *的规则,因为这对于给定的输入更具体。如果我没有使用正则表达式,那将很容易,因为我可以使用评分机制来检查它匹配的程度,但是这些规则可能有一些更高级的正则表达式,例如:

31[89].*

4 个答案:

答案 0 :(得分:4)

我认为没有简单的方法可以做到这一点。如果你看一下更复杂的例子,你很快就会意识到完全定义“更相关”是很困难的。所有诸如断言和反向引用之类的东西都会发挥作用。

我可以想出两种粗略估计“相关性”的方法。

  1. 随机修改输入并比较每个表达式失败的修改次数。

  2. 分析它的表达方式。计算和扼杀终端符号与通配符的数量,断言的数量以及您喜欢的任何内容。

  3. 特别是在第二种解决方案中,您必须意识到实际匹配未使用的许多替代方案可能会使结果无关紧要。

    h.*|verylongtext|anotherverylongtext
    
    hell.*|v.*
    

    当匹配“hello”时,第二个表达式“更相关”,但第一个表达式包含更多的终端符号,并且可能通过第二个解决方案获得更好的排名。但是为了匹配“非常长篇”,第一个是“更相关”。这表明“相关性”在很大程度上取决于实际输入,您必须分析实际匹配路径 - 这是第一个解决方案隐式完成的。但随机修改输入是一项非常艰巨的任务,因为可能的输入空间非常大。我认为这也不会很好。

答案 1 :(得分:1)

我能想到的一个因素是语言是无限的还是无限的。因为语言中存在有限数量的可接受单词,所以无限无限绝对比无限更有意义。

如果像你的例子那样测量无限语言,那么这两种语言都会永远继续下去,你可以继续用语言计算每个单词,直到你脸红了,你永远不会得出结论。

直到您认为第一个正则表达式的语言是第二个语言的正确子集。那么你可能会说一个更相关。

我不知道如何衡量正则表达式的相关性。

要阐明适当子集的概念,你可能会问你的语言是什么,并且你的正则表达式是否接受了除此之外的单词?你的表达可能仍然有效,但它的词汇范围比你想象的要宽......当然,如果你的输入被控制,这可能无关紧要,但这是衡量相关性的一种方式。是接受我的语言完全

你的是一个很好的例子,也许你想接受从1234开始的数字。1234.*就像一个魅力......但这不是你指定的语言。 `1234 \ d *更具体,与您指定的语言完全匹配...因此更具相关性。

但这完全来自纯粹的理论观点,并且可能无法帮助您以编程方式确定一个正则表达式是否优于另一个正则表达式。

答案 2 :(得分:1)

自从我问这个问题已经很久了,但我想让你知道我最终想出了什么。我采用了一种更简单的方法,我只是在正则表达式中添加了权重因子。所以你可以说我自己定义了正则表达式的相关性,而不是试图用正则表达式来定义它:

Expression      Relevance
31.*              1
.*              0

答案 3 :(得分:0)

我不知道“相关性”是否是真正的问题。每个都是相关的,每个都匹配“1234567”,如你所说。然而,正如你所说,一个(“1234. *”)更具体。使用正则表达式,特异性很好(在这种简单的情况下),有时你可以磨练它到目前为止,你知道你毕竟不需要一个(一个正则表达式)。正则表达式的规则#1:如果不需要,请不要使用它们。例如,要匹配“1234567”,我会选择:

$source = '1234567';
if ( stripos( $source, '1234' ) === 0 ) {
  $foo = substr( $source, 4 );
  // $source began with '1234' and $foo holds the rest
} else {
  // it didn't begin with '1234'
}

这是一个PHP示例,但我们的想法是,由于您已经如此严格地磨练了您接受的价值,您甚至不再需要PCRE了。 “相关性”并不会真正告诉你很多正则表达式(在这种情况下你如何定义“相关性”?),但我认为特异性是一种更客观的测量,并且能够使用非正则表达式字符串函数来确定因为它具有非常明显的特定性(事实上,它是布尔值 - 是否有正则表达式?)。

除了能够减少正则表达式之外:要测量给定正则表达式的特异性,只需比较(启发式,如果需要)多少不同的值将满足表达式。在此测试中得分最低的表达式将证明是最具体的。