【问题标题】:Regular expression collision detection正则表达式碰撞检测
【发布时间】:2015-01-14 16:39:45
【问题描述】:

假设两个正则表达式e1e2冲突如果存在任何字符串s,那么e1e2都匹配s。 p>

是否有任何简单(有效)的方法来检查两个正则表达式是否发生冲突,而无需遍历我们字典中所有可能字符串的集合?

注1:我不知道这在文献中是否以其他方式称为。也许我只是缺少正确的名称来搜索这个。

注意 2: 对我来说理想的答案是编写 PHP 代码,但我接受任何建议,不一定是 PHP。

【问题讨论】:

  • 一般来说,这是一个公平的赌注,因为您无法测试构成字符串的每个字符组合,因此您无法比较两个正则表达式来查看它们是否匹配相同的字符串。我说一般是因为正则表达式可能几乎相同,或者范围很广,可以在视觉上发现它。
  • 很抱歉,我没有看到任何重复。使用 AND 运算符需要遍历整个字符串字典,并且问题明确要求不要这样做。
  • 如果你在只匹配一个正则表达式的地方实现了一些东西,如果有匹配,检查你的另一个正则表达式。您可以遍历您的字典,仅检查其中一个,直到您成功为止,而不是检查所有内容都针对这两种模式。
  • 我不确定你能做到这样的事情。假设 e1 = /[a-z]/e2 = /[0-9]/ 它们都匹配 s = 'a1' 但你不能说 e1 matches same thing that e2

标签: php regex optimization preg-match


【解决方案1】:

所以,经过进一步研究,这在文献中似乎被称为正则表达式交集

这是可能的,显然实现起来并不难,但似乎没有官方的PHP支持。

实现简单算法的关键在于将正则表达式转换为有限自动机。阅读随附的链接以更好地了解解决方案。

Stackoverflow 相关问题:

Intersection of two regular expressions

Calculate if two infinite regex solution sets don't intersect

PHP 的非官方库:

https://github.com/KendallHopkins/FormalTheory

编辑:添加代码 sn-p 以使用 Kendall Hopkins 库检查交叉点:

function doRegexIntersection($regex_string_1, $regex_string_2) {
    $lexer = new FormalTheory_RegularExpression_Lexer();
    $nfa1 = $lexer->lex( $regex_string_1 )->getNFA();
    $nfa2 = $lexer->lex( $regex_string_2 )->getNFA();
    return FormalTheory_FiniteAutomata::intersection( $nfa1, $nfa2 )->validSolutionExists();
}

【讨论】:

  • 通过intersection,你的意思是两个正则表达式可能匹配相同的文本吗?如果是这样,这是否意味着不存在与一个匹配的字符串而不是另一个匹配的字符串?我想最后一个问题是这些信息能为您带来什么?
  • 是的,如果交集是一个有效的自动机,这意味着至少有 1 个字符串与两个正则表达式匹配。如果交集为空(即交集自动机无法到达结束状态),则该字符串不存在。我不完全理解你的最后一个问题。这是我正在寻找的解决方案,我有两个对象,它们的行为由正则表达式定义,我需要检查它们是否不相交。
  • 那么如果至少有 1 个字符串被两者匹配,这是否意味着有其他字符串匹配 1 而不是另一个?
  • 不一定。例如,您可以有两个等效的正则表达式,它们都将匹配完全相同的字符串子集。或者您可以在另一个中包含一个正则表达式。试想e1 = ^a.*$e2 = ^.*$,则存在两者都匹配的字符串(例如aa),但是你找不到e1匹配的字符串,而e2不匹配。
  • 好的,如果两个正则表达式可以达到一个共同的最终状态,那么当一个匹配字符串而一个不匹配时,您可以对该信息进行哪些优化?
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-08-12
  • 2011-09-05
  • 2019-04-30
  • 1970-01-01
相关资源
最近更新 更多