
本文讲解如何精准匹配双花括号 {{...}} 内部的连字符 - 并将其替换为下划线 ``,重点解决转义缺失、贪婪匹配和捕获逻辑错误等常见问题,并提供可直接运行的 PHP 示例代码。
本文讲解如何精准匹配双花括号 `{{...}}` 内部的连字符 `-` 并将其替换为下划线 `_`,重点解决转义缺失、贪婪匹配和捕获逻辑错误等常见问题,并提供可直接运行的 php 示例代码。
在模板字符串处理中,常需对双花括号语法(如 {{first-name}})内的变量名进行标准化——例如将连字符 - 统一转为下划线 _。但直接使用 {{.+(-).+}} 这类正则表达式会失败,主要原因有三:
- 未转义元字符:{ 和 } 在正则中是量词符号(如 {3}),必须用反斜杠 \{ 和 \} 显式转义;
- 贪婪匹配越界:.+ 会跨多个 }} 匹配,导致误吞内容(如 {{a}} {{b-c}} 可能被整体捕获);
- 捕获组设计错误:原写法仅捕获一个 -,却试图用 $1_ 替换,但未保留 - 前后内容,造成信息丢失。
✅ 正确方案是:精确限定匹配范围 + 分段捕获 + 安全替换。
推荐正则表达式:
(\{\{[^}]+)-([^}]+\}\})- (\{\{[^}]+):捕获以 {{ 开头、后续为非 } 字符的任意长度子串(即 {{ 到第一个 - 前的部分);
- -:字面量连字符,需被替换的目标;
- ([^}]+\}\}):捕获从 - 后开始、直到 }} 结束的子串([^}]+ 确保不跨越 },避免贪婪越界)。
对应 PHP 代码如下:
$template = 'Hello {{first-name}}, how are you? The event {{event-name-address}}';
$pattern = '/(\{\{[^}]+)-([^}]+\}\})/';
$replacement = '${1}_$2'; // 注意:用 ${1} 避免 $1_ 被解析为变量 $1_
$result = preg_replace($pattern, $replacement, $template);
// 循环替换,确保处理所有连字符(因单次只替换最右一个 -)
while (preg_match($pattern, $result)) {
$result = preg_replace($pattern, $replacement, $result);
}
echo $result;
// 输出:Hello {{first_name}}, how are you? The event {{event_name_address}}⚠️ 关键注意事项:
- 必须使用分隔符(如 /)包裹正则,否则 preg_replace() 会报错;
- ${1} 比 $1 更安全,防止 _ 被误认为变量名的一部分;
- 单次 preg_replace() 仅替换每对 {{}} 中最右侧的一个 -,因此需循环执行直至无匹配(或改用 preg_replace_callback 一次性处理全部 -);
- 若需支持嵌套花括号(极少见),本方案不适用,应改用解析器而非正则。
该方案兼顾准确性与可读性,适用于 Laravel Blade、Twig 或自定义模板引擎中的变量名规范化场景。

















