这个问题已经在这里有一个答案:
- 为什么会出现这种逆向引用不是回顾后里面工作? 1个回答
TL; DR:使用捕捉(特别是均衡组).NET的lookbehinds内改变获得的捕获,但它不应该有所作为。 用什么.NET的lookbehinds是它打破预期的行为?
我试图想出一个答案, 这个问题等 ,以此为借口与.NET的平衡群体玩耍。 但是,我不能让他们到一个可变长度的回顾后内工作。
首先,请注意,我不打算来有效地利用这个特殊的解决方案。 它更学术的原因,因为我觉得有一些与可变长度的回顾后,我是不知道的事情。 而明知可能派上用场的未来,当我真正需要使用像这样来解决问题。
考虑此输入:
~(a b (c) d (e f (g) h) i) j (k (l (m) n) p) q
我们的目标是匹配所有的字母,这是由前括号内~
,没有多么深跌(所以一切从a
到i
)。 我的尝试是检查在回顾后的正确位置,这样我可以得到所有的信件中单个呼叫Matches
。 这里是我的模式:
(?<=~[(](?:[^()]*|(?<Depth>[(])|(?<-Depth>[)]))*)[a-z]
在回顾后我试图找到一个~(
然后我用命名的堆叠组Depth
计算无关的左括号,只要在开括号~(
永远不会关闭,回顾后应该匹配。如果右括号到达到, (?<-Depth>...)
不能从栈中弹出任何与回顾后应该会失败(即,从所有字母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
并根据需要,所有的情况相符,其中z
取代之间的字母a
和i
和所有的案件后失效。
那么,是什么的(可变长度)回顾后做,打破了这种平衡使用群体? 我试图研究这个一晚上(发现类似的网页这一个 ),但我不能找到一个回顾后单次使用的这一点。
我也很高兴,如果有人可以链接我一些深入有关.NET正则表达式引擎内部是怎样处理.NET特有的功能的信息。 我发现这个惊人的文章 ,但它似乎并没有进入(可变长度)lookbehinds,例如。
我想我得到了它。
首先,如我在评论中的一个所提到的, (?<=(?<A>.)(?<-A>.))
从不匹配。
但转念一想,怎么样(?<=(?<-A>.)(?<A>.))
它不匹配!
和怎么样(?<=(?<A>.)(?<A>.))
匹配的对"12"
, A
被抓住"1"
,如果我们看一下Captures
集合,它是{"2", "1"}
-前两个,然后一个-它是相反的。
因此,虽然一个回顾后内,.NET比赛和从向左向右捕获 。
现在,我们怎样才能让它在捕捉从左至右? 这是很简单的,真的 - 我们可以使用一个超前欺骗引擎:
(?<=(?=(?<A>.)(?<A>.))..)
适用于原来的彭定康,我想出了一个简单的方法是:
(?<=
~[(]
(?=
(?:
[^()]
|
(?<Depth>[(])
|
(?<-Depth>[)])
)*
(?<=(\k<Prefix>)) # Make sure we matched until the current position
)
(?<Prefix>.*) # This is captured BEFORE getting to the lookahead
)
[a-z]
这里的挑战是,现在的平衡部分可以在任何地方结束,所以我们做这一切的方式达到当前位置(喜欢的东西\G
或\Z
在这里很有用,但我不认为.NET有)
这是非常可能的这种行为被记录在案的地方,我会尽力查找。
这里的另一种方法。 这个想法很简单 - .NET想从右侧匹配剩下什么? 精细! 拿着它:
(提示: 开始从底部读 -这是.NET怎么做的)
(?<=
(?(Depth)(?!)) # 4. Finally, make sure there are no extra closed parentheses.
~\(
(?> # (non backtracking)
[^()] # 3. Allow any other character
|
\( (?<-Depth>)? # 2. When seeing an open paren, decreace depth.
# Also allow excess parentheses: '~((((((a' is OK.
|
(?<Depth> \) ) # 1. When seeing a closed paren, add to depth.
)*
)
\w # Match your letter
我认为这个问题是与数据,而不是模式。 该数据有哪些需要“邮报”的项目进行匹配,如
(AB(c)中DEF)
其中需要去和F相匹配。 一个更平衡的数据将是
(AB(C)(d)(E)(F))
所以我把这个例子的数据粘性需要括号之后的后续匹配情况:
〜(AB(C)d(EF(克)H)ⅰ)JK
其中J&K应该被忽略......我的模式失败,抓获了他们。
有趣的是,我命名捕获组,找出他们来到其中j和k在拍摄三人来到英寸 我离开你,不是一个答案,但尝试看看是否可以改进它。
(~ # Anchor to a Tilde
( # Note that \x28 is ( and \x29 is )
( # --- PRE ---
(?<Paren>\x28)+ # Push on a match into Paren
((?<Char1>[^\x28\x29])(?:\s?))*
)+ # Represents Sub Group 1
( #---- Closing
((?<Char2>[^\x28\x29])(?:\s?))*
(?<-Paren>\x29)+ # Pop off a match from Paren
)+
(
((?<Char3>[^\x28\x29])(?:\s?))* # Post match possibilities
)+
)+
(?(Paren)(?!)) # Stop after there are not parenthesis
)
这里是比赛与我有我自己的(也许有一天我会公布)创建的工具进行细分。 需要注意的是˽显示了一个空间被匹配。
Match #0
[0]: ~(a˽b˽(c)˽d˽(e˽f˽(g)˽h)˽i)˽j˽k
["1"] → [1]: ~(a˽b˽(c)˽d˽(e˽f˽(g)˽h)˽i)˽j˽k
→1 Captures: ~(a˽b˽(c)˽d˽(e˽f˽(g)˽h)˽i)˽j˽k
["2"] → [2]: (e˽f˽(g)˽h)˽i)˽j˽k
→2 Captures: (a˽b˽(c)˽d˽, (e˽f˽(g)˽h)˽i)˽j˽k
["3"] → [3]: (g
→3 Captures: (a˽b˽, (c, (e˽f˽, (g
["4"] → [4]: g
→4 Captures: a˽, b˽, c, e˽, f˽, g
["5"] → [5]: ˽i)
→5 Captures: ), ), ˽h), ˽i)
["6"] → [6]: i
→6 Captures: ˽, h, ˽, i
["7"] → [7]:
→7 Captures: ˽d˽, , ˽j˽k,
["8"] → [8]: k
→8 Captures: ˽, d˽, ˽, j˽, k
["Paren"] → [9]:
["Char1"] → [10]: g
→10 Captures: a, b, c, e, f, g
["Char2"] → [11]: i
→11 Captures: ˽, h, ˽, i
["Char3"] → [12]: k
→12 Captures: ˽, d, ˽, j, k