TL;DR: 在.NET中使用捕获(特别是平衡组)时,位于回顾后面的内容发生了变化,尽管它不应该有任何影响。这是.NET回顾后面的什么问题,导致预期行为被破坏了吗?
我试图回答另一个问题此处链接未提供并借此机会玩一下.NET的平衡组。然而,我无法让它们在可变长度回顾后面正常工作。
首先,请注意,我并不打算以这种特定的解决方案来实现生产力。这更多是出于学术原因,因为我感觉在可变长度回顾后面发生了一些事情,我还没有意识到。当我实际上需要使用此类方法来解决问题时,了解这一点可能会派上用场。
考虑以下输入:
在lookbehind中,我试图找到一个
这似乎意味着当我关闭一个单独的括号时,回溯无法匹配任何内容,除非我回到之前到达的最高嵌套级别。
好的,这可能只是我的正则表达式有些奇怪,或者我没有正确理解平衡组。但是我尝试了一下不使用回溯。我为每个字母创建了一个字符串,如下所示:
我试图回答另一个问题此处链接未提供并借此机会玩一下.NET的平衡组。然而,我无法让它们在可变长度回顾后面正常工作。
首先,请注意,我并不打算以这种特定的解决方案来实现生产力。这更多是出于学术原因,因为我感觉在可变长度回顾后面发生了一些事情,我还没有意识到。当我实际上需要使用此类方法来解决问题时,了解这一点可能会派上用场。
考虑以下输入:
~(a b (c) d (e f (g) h) i) j (k (l (m) n) p) q
目标是匹配所有在括号内的字母,这些括号前面有一个波浪线~
,无论多深(所以从a
到i
的所有内容)。我的尝试是在回顾中检查正确的位置,以便我可以在单个调用Matches
中获取所有字母。这是我的模式:
(?<=~[(](?:[^()]*|(?<Depth>[(])|(?<-Depth>[)]))*)[a-z]
在lookbehind中,我试图找到一个
~(
,然后使用命名组堆栈Depth
来计算多余的开括号。只要在~(
中打开的括号从未关闭,lookbehind就应该匹配。如果到达了那个关闭括号,(?<-Depth>...)
无法从堆栈中弹出任何内容,lookbehind就会失败(也就是说,对于所有字母从j
开始)。不幸的是,这并不起作用。相反,我匹配了a
、b
、c
、e
、f
、g
和m
。因此,只有这些:~(a b (c) _ (e f (g) _) _) _ (_ (_ (m) _) _) _
这似乎意味着当我关闭一个单独的括号时,回溯无法匹配任何内容,除非我回到之前到达的最高嵌套级别。
好的,这可能只是我的正则表达式有些奇怪,或者我没有正确理解平衡组。但是我尝试了一下不使用回溯。我为每个字母创建了一个字符串,如下所示:
~(z b (c) d (e f (x) y) g) h (i (j (k) l) m) n
~(a z (c) d (e f (x) y) g) h (i (j (k) l) m) n
~(a b (z) d (e f (x) y) g) h (i (j (k) l) m) n
....
~(a b (c) d (e f (x) y) g) h (i (j (k) l) z) n
~(a b (c) d (e f (x) y) g) h (i (j (k) l) m) z
我使用这个模式对每个元素进行了操作:
~[(](?:[^()]*|(?<Depth>[(])|(?<-Depth>[)]))*z
根据要求,所有 a
和 i
之间的字母都可以用 z
替换,所有替换后的情况都匹配成功,但在此之后的所有情况都匹配失败。
那么,这个(可变长度)回顾机制做了什么破坏了这种平衡组的使用呢?我试图整晚研究这个问题(并找到了像this one这样的页面),但我找不到一个在回顾机制中使用这个的例子。
如果有人能够链接一些深入的信息,让我了解.NET正则表达式引擎如何处理.NET特定的内部功能,我也会很高兴。我发现this amazing article,但它似乎没有涉及(可变长度)回顾机制等内容。
a
到i
的所有字母。重点不在于找到一个正确匹配的算法,而是要找到当我将平衡组和后置断言结合使用时出现奇怪行为的解释。 - Martin Ender(?<=(?<A>.)(?<-A>.))
的东西永远不会匹配。我期望它能够匹配第二个位置之后的任何位置。然而,(?<A>)(?<=(?<A>.)(?<-A>.))(?<-A>)
可以匹配这些位置(尽管在你的情况下类似的方法不起作用)。我要注意的是 Mono 表现完全相同:http://ideone.com/rvmQhr - 对于你的模式 http://ideone.com/Hjb3jn - 所以可能有一些规范解释了这一点。 - Kobi