You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PHP v8 preg_match_all匹配嵌套双花括号令牌及文本的正则需求

匹配嵌套双花括号令牌的PHP正则方案

需求说明

使用PHP 8的preg_match_all函数,实现两类内容的精准匹配:

  • 普通字面文本(允许包含单花括号{/})
  • 最外层双花括号令牌{{...}},支持令牌嵌套,仅捕获最外层结构;令牌内部允许出现单花括号,仅{{和}}作为令牌的起始/结束分隔符。

示例输入

This {is {{Par}m1}} plus {{Par{m3a{{Parm3b}}}} a}nd {{Parm4a||{{Par}m4b||{{Parm4c||{{Parm4d||Parm}}}}}}}}.

预期匹配结果

Match 1: This {is
Match 2: {{Par}m1}}
Match 3:  plus
Match 4: {{Par{m3a{{Parm3b}}}}
Match 5:  a}nd
Match 6: {{Parm4a||{{Par}m4b||{{Parm4c||{{Parm4d||Parm}}}}}}}}
Match 7: .

现有方案问题

  • 原正则(?:(?!(\{\{)).)+|((\{\{)((?>[^\{\}]+|(?2))*)(\}\})):无法兼容含单花括号的场景,[^\{\}]+会排除所有单花括号,导致令牌内的单花括号被截断。
  • 递归正则\{\{(?R)*\}\|[^\{\}]+:逻辑错误,未正确处理单花括号,匹配规则混乱,无法完成预期解析。

解决方案正则

$pattern = '~(?:(?!{{).)+|({{(?:[^{}]|{(?![{])|}(?![}])|(?R))*}})~s';
preg_match_all($pattern, $input, $matches, PREG_PATTERN_ORDER);
$results = $matches[0];

正则解析

  • 分隔符:使用~作为正则分隔符,避免与花括号冲突
  • s修饰符:让.匹配换行符,提升通用性
  • 第一分支(?:(?!{{).)+:匹配普通文本
    • (?!{{):负前瞻断言,确保当前位置后不是令牌起始符{{
    • .:匹配任意字符(含单花括号),重复匹配直到遇到{{或字符串结束
  • 第二分支({{(?:[^{}]|{(?![{])|}(?![}])|(?R))*}}):匹配最外层令牌
    • {{:匹配令牌起始标记
    • 内部非捕获组(?:...)定义令牌允许的内容:
      • [^{}]:匹配非花括号的任意字符
      • {(?![{]):匹配单个{(排除{{)
      • }(?![}]):匹配单个}(排除}})
      • (?R):递归调用整个正则模式,实现嵌套令牌的匹配
    • *:重复匹配内部内容,直到遇到对应的}}
    • }}:匹配令牌结束标记

验证结果

将示例输入代入上述代码,$results数组将完全符合预期匹配结果,可正确区分普通文本与最外层嵌套令牌,完美兼容单花括号场景。

内容的提问来源于stack exchange,提问作者Russ

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.24 23:07:51