Regex 所有正则表达式都停止吗?

Regex 所有正则表达式都停止吗?,regex,halting-problem,Regex,Halting Problem,对于某些输入字符串,是否有任何正则表达式会永远搜索匹配项?与您描述的意思不同,您可能会有一些效率非常低的正则表达式,它们占用大量资源,最终导致正则表达式引擎停止运行,这与停止运行不同 我不认为停下来真的适用于这里,正如这篇文章的其他评论者如此敏锐地指出的那样。 根据,每个正则表达式都会停止。我想,不可能找到一个不停止的正则表达式 输入的大小是有限的。正则表达式的任何匹配子组的最大大小都是输入的最大大小 除非所使用的算法非常愚蠢(多次检查案例),否则匹配的子组的数量也将是有限的 因此,它将停止。我

对于某些输入字符串,是否有任何正则表达式会永远搜索匹配项?

与您描述的意思不同,您可能会有一些效率非常低的正则表达式,它们占用大量资源,最终导致正则表达式引擎停止运行,这与停止运行不同

我不认为停下来真的适用于这里,正如这篇文章的其他评论者如此敏锐地指出的那样。
根据,每个正则表达式都会停止。

我想,不可能找到一个不停止的正则表达式

输入的大小是有限的。正则表达式的任何匹配子组的最大大小都是输入的最大大小

除非所使用的算法非常愚蠢(多次检查案例),否则匹配的子组的数量也将是有限的


因此,它将停止。

我无法想象一个输入字符串将永远被解析,尽管一个无限长的字符串将永远被解析。假设正则表达式可以描述一种正则语言,它可能是一组无限的单词,那么正则表达式可以描述一种包含无限单词的语言,包括无限长的单词。然而,没有一个输入字符串可以无限长,所以在某个时候它必须停止


例如,如果语言中接受了a*b,并且有一个无限长的“a”字符串,那么是的,正则表达式将永远不会停止。但实际上,这是不可能的。

形式正则表达式实际上是一种描述解析字符串的确定性有限自动机的方法。如果DFA在输入结束时处于接受状态,则正则表达式“匹配”。由于DFA按顺序读取其输入,因此当它到达输入的末尾时,它将始终停止,而是否存在匹配仅仅是检查它停止在哪个DFA状态的问题

子字符串匹配实际上是相同的,除了在字符串的一次读取结束时被迫停止之外,DFA将在读取每个可能的子字符串一次后被迫停止,这仍然是一种有限的情况。(是的,大多数正则表达式引擎以一种更优化的方式实现了这一点,而不仅仅是在DFA中抛出每个可能的子字符串——但从概念上讲,它的限制仍然存在)


因此,DFA不会停止的唯一可能情况是输入是无限的,这通常被认为超出了停止问题的范围。

对于有限输入,没有不停止的形式正则表达式

任何形式正则表达式都可以转化为确定性有限自动机。DFA一次读取一个字符的输入,在输入结束时,您要么处于接受状态,要么处于不接受状态。如果状态为接受,则输入与正则表达式匹配。否则,它不会

现在,大多数“正则表达式”库都支持非正则表达式的内容,例如反向引用。只要你远离这些特性,并且有一个有限的输入,你就一定会停止。如果你不。。。根据您使用的具体内容,很可能无法保证停止。例如,Perl允许插入任意代码,并且不保证停止与图灵机等价的任意代码

现在,如果输入是无限的,那么可以找到永不停止的平凡正则表达式。例如,“
*

正则表达式可以用有限状态机表示。每次您接收到原子输入时,它都会导致任何定义良好的FSM转换到已知状态

例外情况是当您有无限输入时,但这不适用于停止问题,因为它处理有限输入。当您有一个有限状态机和有限输入时,总是可以确定您的机器是否将停止


丹尼尔的答案是:所有有限的输入都会导致真正的正则表达式(即,没有反向引用或其他非正则表达式特性)停止,正则表达式等同于DFA

好处:正则表达式匹配可以简单快速 (但在Java、Perl、PHP、Python、Ruby等方面速度较慢)


请注意,本文顶部的两个图表在y轴上有不同的刻度:一个是秒,另一个是微秒

。。。你能写一个程序来决定一个正则表达式是否会因为一个给定的输入而停止吗?为了获得额外的分数-使用正则表达式!当然,mmyers和mgb-只需对连接到regex的输入运行此命令:/.*/-匹配表示它停止,不匹配表示它不:这个程序很简单。我将用python表示它:True。--至于接受字符串,那就是“在输入i上运行regexr,返回它返回的内容。”没有一种方法可以生成一个程序,因为每个可能的程序都会告诉你它是否停止。但这并不意味着你不能为一个子集这样做。也许正则表达式就是这样一个子集,但我不知道;用于重新匹配的算法是一种特殊的算法,关于停止问题的有趣之处在于解决所有程序输入对的问题。是的,这就是我在回答中试图说的。唯一的疑问是:它们被称为确定性有限自动机,而不是确定性的。与(讽刺的是,等价的)非确定性有限自动机形成对比。@Agor:我讨厌这样做。我很清楚正确的名字,但出于某些原因,我总是键入错误的名字-(