获取所有嵌套的花括号

dro*_*lot 2 php regex preg-match-all preg-match

可以从字符串中获取嵌套花括号中的所有内容吗?例如:

敏捷的棕色狐狸跳过了懒狗

所以我需要:

  • 过了
  • 跳过{懒惰}

从大多数嵌套的顺序来看,这个顺序更好.

nha*_*tdh 8

下面的正则表达式将允许您获取所有嵌套花括号的内容.请注意,这假设嵌套的花括号是平衡的; 否则,很难定义答案应该是什么.

(?=\{((?:[^{}]++|\{(?1)\})++)\})
Run Code Online (Sandbox Code Playgroud)

结果将是捕获组1.

DEMO

但请注意,顺序不是问题中指定的顺序.打印出的订单由开口大括号的外观顺序定义{,这意味着最外面的一对的内容将首先打印出来.

说明

暂时忽略零宽度正向 前瞻(?=pattern),让我们专注于内部模式,即:

\{((?:[^{}]++|\{(?1)\})++)\}
Run Code Online (Sandbox Code Playgroud)

2个文字花括号之间的部分 - ((?:[^{}]++|\{(?1)\})++)将匹配以下任一个的一个或多个实例:

  • 一个非空的非大括号的字符序列[^{}]++,或
  • 递归地匹配由其包围的块{},其可以包含许多其他非大括号序列或其他块.

仅上面的模式可以匹配不包含的文本{},这是我们不需要的.因此,我们确保匹配是{}由两端的花括号括起来的块{}:\{((?:[^{}]++|\{(?1)\})++)\}.

由于我们希望所有嵌套花括号内的内容,我们需要阻止引擎使用文本.这就是使用零宽度正向前瞻的方式.

它不是非常有效,因为你将重做嵌套括号的匹配,但我怀疑还有任何其他通用解决方案与正则表达式可以有效地处理它.

普通代码可以一次性有效地处理所有内容,如果您将来要扩展您的需求,建议使用.