正如其他答案所声称的那样,环顾四周不会为正则表达式增加任何额外的功能。
我认为我们可以使用以下方法来展示这一点:
One Pebble 2-NFA(参见论文的引言部分)。
1-pebble 2NFA 不处理嵌套的前瞻,但是,我们可以使用 multi-pebble 2NFA 的变体(请参阅下面的部分)。
简介
2-NFA 是一个非确定性的有限自动机,它能够根据输入向左或向右移动。
单鹅卵石机器是机器可以在输入磁带上放置鹅卵石(即用鹅卵石标记特定输入符号)并根据当前输入位置是否有鹅卵石进行可能的不同转换。
众所周知,One Pebble 2-NFA 具有与常规 DFA 相同的功能。
非嵌套前瞻
基本思路如下:
2NFA 允许我们通过在输入磁带中向前或向后移动来回溯(或“前轨”)。因此,对于前瞻,我们可以对前瞻正则表达式进行匹配,然后回溯我们所消耗的内容,以匹配前瞻表达式。为了准确知道何时停止回溯,我们使用了鹅卵石!我们在进入 dfa 之前放下鹅卵石进行前瞻,以标记回溯需要停止的位置。
因此,在我们的字符串通过 pebble 2NFA 运行结束时,我们知道我们是否匹配了前瞻表达式,并且输入 left(即剩下要消耗的内容)正是匹配剩余部分所需的内容。
所以对于 u(?=v)w 形式的前瞻
我们有 u、v 和 w 的 DFA。
从 u 的 DFA 的接受状态(是的,我们可以假设只有一个),我们向 v 的开始状态进行电子转换,用鹅卵石标记输入。
从 v 的接受状态,我们 e 转换到不断向左移动输入的状态,直到找到一个 pebble,然后转换到 w 的开始状态。
从 v 的拒绝状态,我们电子转移到一个不断向左移动直到找到卵石的状态,然后转移到 u 的接受状态(即我们离开的地方)。
用于显示 r1 的常规 NFA 的证明 | r2 或 r* 等用于这些 2nfas 的卵石。请参阅http://www.coli.uni-saarland.de/projects/milca/courses/coal/html/node41.html#regularlanguages.sec.regexptofsa,了解有关如何将组件机器组合在一起为 r* 表达式等提供更大机器的更多信息。
上述 r* 等证明起作用的原因是,当我们进入组件 nfas 进行重复时,回溯确保输入指针始终位于正确的位置。此外,如果正在使用卵石,则它正在由其中一台前瞻组件机器进行处理。由于没有完全回溯和取回卵石,就没有从前瞻机器到前瞻机器的过渡,因此只需要一台卵石机器。
例如考虑 ([^a] | a(?=...b))*
还有字符串abbb。
我们有abbb,它通过peb2nfa for a(?=...b),最后我们处于状态:(bbb,matched)(即输入中的bbb是剩余的,并且已经匹配'a' 后跟 '..b')。现在因为有 *,我们回到开头(参见上面链接中的构造),并为 [^a] 输入 dfa。匹配b,回到开头,再次输入[^a]两次,然后接受。
处理嵌套的前瞻
要处理嵌套的前瞻,我们可以使用此处定义的 k-pebble 2NFA 的受限版本:Complexity Results for Two-Way and Multi-Pebble Automata and their Logics(参见定义 4.1 和定理 4.2)。
一般来说,2个卵石自动机可以接受非正则集,但有以下限制,可以证明k-卵石自动机是正则集(上述论文中的定理4.2)。
如果鹅卵石是 P_1, P_2, ..., P_K
P_{i+1} 可能不会被放置,除非 P_i 已经在磁带上,并且 P_{i} 可能不会被拾取,除非 P_{i+1} 不在磁带上。基本上,鹅卵石需要以 LIFO 方式使用。
在 P_{i+1} 放置时间和 P_{i} 被拾取或 P_{i+2} 放置时间之间,自动机只能遍历位于当前P_{i} 的位置和位于 P_{i+1} 方向上的输入词的结尾。此外,在这个子词中,自动机只能作为具有 Pebble P_{i+1} 的 1-pebble 自动机。尤其是不允许举起、放置甚至感知另一块鹅卵石的存在。
因此,如果 v 是深度为 k 的嵌套前瞻表达式,则 (?=v) 是深度为 k+1 的嵌套前瞻表达式。当我们进入其中的前瞻机器时,我们确切地知道到目前为止必须放置多少个鹅卵石,因此可以准确地确定要放置哪个鹅卵石,当我们退出该机器时,我们知道要举起哪个鹅卵石。通过放置 pebble t 进入深度 t 的所有机器,并通过移除 pebble t 退出(即我们返回到深度 t-1 机器的处理)。整机的任何运行看起来都像是树的递归dfs调用,可以满足多卵石机的上述两个限制。
现在当你组合表达式时,对于 rr1,由于你 concat,r1 的卵石数必须增加 r 的深度。对于 r* 和 r|r1,卵石编号保持不变。
因此,任何具有前瞻的表达式都可以转换为具有上述 pebble 放置限制的等效多 pebble 机器,因此是常规的。
结论
这基本上解决了 Francis 原始证明中的缺点:能够防止前瞻表达式消耗未来匹配所需的任何内容。
由于 Lookbehinds 只是有限字符串(不是真正的正则表达式),我们可以先处理它们,然后再处理前瞻。
很抱歉写的不完整,但完整的证明需要画很多图。
这对我来说是正确的,但我很高兴知道任何错误(我似乎很喜欢:-))。