【问题标题】:Mutually exclusive regular expressions互斥正则表达式
【发布时间】:2011-02-27 10:06:02
【问题描述】:

如果我有一个正则表达式列表,是否有一种简单的方法可以确定它们中的任何一个都不会返回相同字符串的匹配项?

也就是说,当且仅当对于所有字符串,列表中最多有一项与整个字符串匹配时,列表才有效。

这似乎很难(也许不可能?)明确地证明,但我似乎找不到任何关于这个主题的工作。

我问的原因是我正在开发一个接受正则表达式的标记器,我想确保一次只有一个标记可以匹配输入的头部。

【问题讨论】:

  • 我想我误解了。您的意思是两个给定的正则表达式必须与 any 输入字符串完全互斥?即,在 2^32 个可能的四字节字符串中,正则表达式可能只匹配一种可能性?这不就是说:匹配这个确切的字符串吗?
  • 我的意思是正则表达式的交集必须为零。没有字符串匹配超过 1 个正则表达式。
  • 此外,我应该注意我说的是有效的 c# 正则表达式。
  • 那么,恐怕我原来的答案仍然成立(以及吉姆答案的最后一段)。您不能这样做,仅仅是因为这些 C#(它们是 NFA)正则表达式的本质。 (PS:我删除了我的,因为它太糟糕了。去吉姆的)

标签: regex mutual-exclusion


【解决方案1】:

如果您使用的是纯正则表达式(没有反向引用或其他导致它们识别上下文无关或更复杂语言的功能),您可以提出问题。 您可以做的是将每个正则表达式转换为 DFA,然后(因为常规语言在交集下关闭)将它们组合成一个可以识别的 DFA 两种语言的交集。如果该 DFA 具有从开始状态到接受状态的路径,则该字符串被两个输入正则表达式接受。

问题在于,通常的 regex->DFA 算法的第一步是 将正则表达式转换为 NFA,然后将 NFA 转换为 DFA。但是最后一步可以 导致 DFA 状态的数量呈指数级增长,所以这只会是 对于非常简单的正则表达式是可行的。

如果您正在使用扩展的正则表达式语法,那么所有的赌注都没有:上下文无关语言 没有在路口关闭,所以这个方法不起作用。

【讨论】:

  • 有趣的想法。我认为您实际上是在与 Jeffrey Friedl 交锋,他说(第 157 页)“谈论 DFA 匹配非常无聊”。您刚刚又让它变得有趣了(接受 DFA 仍然高度限制您)!
  • 这就是我所担心的。非常有趣的答案。
【解决方案2】:

你不能只看正则表达式来做到这一点。

考虑您拥有[0-9][0-9]+ 的情况。它们显然是不同的表达式,但是当应用于字符串“1”时,它们都会产生相同的结果。当应用于字符串“11”时,它们会产生不同的结果。

关键是正则表达式的信息不够。结果取决于正则表达式和目标字符串。

【讨论】:

  • “当应用于字符串“11”时,它们会产生不同的结果。” 实际上:它们不会,它们会产生相同的结果。除非你添加锚定。
  • 对于纯正则表达式,CaptnCraig 的要求是可能的(但可能效率低下)。他想知道两种正则语言(由正则表达式指定)是否有非空交集。对于您的示例,答案是“是”。
  • @Abel:我认为他的意思是他们匹配的字符串部分不同。不过,它们都会匹配。
  • 对不起,我的问题很糟糕。也许我的意思是在位置 0 只有一个匹配。
  • @Jim:你怎么发现可以找到两个无限集的交集?你能详细说明吗? @Matti:确实,它们匹配不同的部分(除非你有一个非贪婪的引擎,但这很少见,但它确实发生了):)
【解决方案3】:

Wkipedia article on regular expressions 确实声明了

可以编写一个算法,对两个给定的正则表达式确定所描述的语言是否本质上相等,将每个表达式简化为最小确定性有限状态机,并确定它们是否同构(等价)。

但没有给出进一步的提示。

当然,您所追求的简单方法是运行大量测试——但我们都知道测试作为证明方法的缺点。

【讨论】:

  • 我相信 CaptnCraig 想知道语言是否有非空交集,而不是它们是否相同。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-12-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多