平衡基团在可变长度回顾后[重复](Balancing groups in variable-leng

2019-06-21 04:09发布

这个问题已经在这里有一个答案:

  • 为什么会出现这种逆向引用不是回顾后里面工作? 1个回答

TL; DR:使用捕捉(特别是均衡组).NET的lookbehinds内改变获得的捕获,但它不应该有所作为。 用什么.NET的lookbehinds是它打破预期的行为?

我试图想出一个答案, 这个问题等 ,以此为借口与.NET的平衡群体玩耍。 但是,我不能让他们到一个可变长度的回顾后内工作。

首先,请注意,我不打算来有效地利用这个特殊的解决方案。 它更学术的原因,因为我觉得有一些与可变长度的回顾后,我是不知道的事情。 而明知可能派上用场的未来,当我真正需要使用像这样来解决问题。

考虑此输入:

~(a b (c) d (e f (g) h) i) j (k (l (m) n) p) q

我们的目标是匹配所有的字母,这是由前括号内~ ,没有多么深跌(所以一切从ai )。 我的尝试是检查在回顾后的正确位置,这样我可以得到所有的信件中单个呼叫Matches 。 这里是我的模式:

(?<=~[(](?:[^()]*|(?<Depth>[(])|(?<-Depth>[)]))*)[a-z]

在回顾后我试图找到一个~(然后我用命名的堆叠组Depth计算无关的左括号,只要在开括号~(永远不会关闭,回顾后应该匹配。如果右括号到达到, (?<-Depth>...)不能从栈中弹出任何与回顾后应该会失败(即,从所有字母j 。)不幸的是,这并不工作,而不是,我匹配abcefgm因此,只有这些:

~(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取代之间的字母ai和所有的案件后失效。

那么,是什么的(可变长度)回顾后做,打破了这种平衡使用群体? 我试图研究这个一晚上(发现类似的网页这一个 ),但我不能找到一个回顾后单次使用的这一点。

我也很高兴,如果有人可以链接我一些深入有关.NET正则表达式引擎内部是怎样处理.NET特有的功能的信息。 我发现这个惊人的文章 ,但它似乎并没有进入(可变长度)lookbehinds,例如。

Answer 1:

我想我得到了它。
首先,如我在评论中的一个所提到的, (?<=(?<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


Answer 2:

我认为这个问题是与数据,而不是模式。 该数据有哪些需要“邮报”的项目进行匹配,如

(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


文章来源: Balancing groups in variable-length lookbehind [duplicate]