PHP模板带分隔符多变量替换正则匹配异常问题求解
问题根因
原正则/{([a-z_]+)\|?([a-z-]+)}/的第二个捕获组([a-z-]+)使用了+量词,要求至少匹配1个字符;而\|?仅将竖杠设为可选,没有将第二个属性整体设为可选。当变量没有第二个属性时,正则会裁剪第一个捕获组的最后一个符合[a-z-]规则的字符来满足第二个捕获组的匹配要求,最终导致变量名丢失最后一个字符。
修正方案
将竖杠和第二个属性整体设为可选,搭配非捕获组避免生成无用的匹配项,修正后正则为/{([a-z_]+)(?:\|([a-z-]+))?}/。其中:
(?:xxx)为非捕获组标识,不会额外占用匹配结果的索引位- 整个
(?:\|([a-z-]+))?块只有存在|时才会触发匹配,无第二个属性时$matches[2]自动为空,不会抢占第一个捕获组的字符
完整可运行代码
$content = 'Lorem ipsum {monthly_price} and {yearly_price|site-network} Lorem ipsum'; function get_replacement($matches) { $attr = $matches[1]; // 第一个属性,必存在 $deal = $matches[2] ?? ''; // 第二个属性,不存在时默认赋值为空字符串 // 此处可根据业务需求自定义替换逻辑,示例直接返回第一个属性 return $attr; } $content = preg_replace_callback('/{([a-z_]+)(?:\|([a-z-]+))?}/', 'get_replacement', $content); echo $content;
运行结果
Lorem ipsum monthly_price and yearly_price Lorem ipsum
内容的提问来源于stack exchange,提问作者Drewsdesign
相关产品推荐
相关产品推荐

