(.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 平衡组。