Skip to content

Latest commit

 

History

History
45 lines (34 loc) · 1.64 KB

File metadata and controls

45 lines (34 loc) · 1.64 KB

附录 A NET 专有平衡组与递归匹配

上一章:进阶索引 · 目录


(.NET 专有 / 非 PCRE 默认)

嵌套括号、嵌套标签这类「层层配对」,不能靠贪婪的 \(.+\) 保证左右数量相等。.NET 提供命名捕获堆栈(平衡组)来计数:

模式 含义
(?'group'…) / (?<group>…) 捕获并压栈
(?'-group'…) / (?<-group>…) 弹出名为 group 的最后一次捕获;栈空则失败
(?(group)yes|no) 栈上还有 group 则走 yes,否则走 no
(?!) 永远失败的负先行(用来在「栈还没空」时让整次匹配失败)

用尖括号代替圆括号,避免和分组括号缠在一起。教学结构(匹配最长的配对 <…>)大致是:

<                     # 最外层左括号
[^<>]*
(
  (
    (?'Open'<)        # 左:压入 Open
    [^<>]*
  )+
  (
    (?'-Open'>)       # 右:弹出 Open
    [^<>]*
  )+
)*
(?(Open)(?!))         # 还有没配对的 Open 就失败
>
  • ✓ 匹配(.NET): xx <aa <bbb> <bbb> aa> yy 里最长的那对尖括号及其中内容
  • ✗ 不匹配: 左右数量对不上、且引擎无法通过回溯缩成配对结构时
  • 引擎: (.NET 专有 / 非 PCRE 默认)。在 regex101 请改 Flavor 为 .NET 再试。PCRE 请用递归,例如匹配一层圆括号:\((?:[^()]|(?R))*\)。

把 (?'name'exp) 只当作「另一种命名组写法」时,PCRE 也认识;把同一套语法当成堆栈计数,才是 .NET 平衡组。


上一章:进阶索引 · 目录