【问题标题】:Avoid backreference replacement in php's preg_replace避免在 php 的 preg_replace 中替换反向引用
【发布时间】:2016-10-10 23:34:33
【问题描述】:

考虑下面使用preg_replace

$str='{{description}}';
$repValue='$0.0 $00.00 $000.000 $1.1 $11.11 $111.111';

$field = 'description';
$pattern = '/{{'.$field.'}}/';

$str =preg_replace($pattern, $repValue, $str );
echo $str;


// Expected output: $0.0 $00.00 $000.000 $1.1 $11.11 $111.11
// Actual output:   {{description}}.0 {{description}}.00 {{description}}0.000 .1 .11 1.111 

这是phpFiddle showing the issue

我很清楚,实际输出与预期不符,因为 preg_replace 正在查看 $0, $0, $0, $1, $11, and $11 作为匹配组的反向引用,将 $0 替换为完整匹配,将 $1 and $11 替换为空字符串,因为没有捕获组 1 或 11。

如何防止preg_replace 将我的重置价值中的价格视为反向引用并尝试填充它们?

注意$repValue是动态的,操作前不知道其内容。

【问题讨论】:

  • 您确定需要使用preg_replace,而不是str_replace
  • @Barmar,你说得对,我其实可以用str_replace,谢谢

标签: php regex preg-replace pcre


【解决方案1】:

在使用字符转换之前转义美元字符 (strtr):

$repValue = strtr('$0.0 $00.00 $000.000 $1.1 $11.11 $111.111', ['$'=>'\$']);

对于更复杂的情况(美元和逃逸的美元),您可以进行这种替换(这次完全防水)

$str = strtr($str, ['%'=>'%%', '$'=>'$%', '\\'=>'\\%']);
$repValue = strtr($repValue, ['%'=>'%%', '$'=>'$%', '\\'=>'\\%']);
$pattern = '/{{' . strtr($field, ['%'=>'%%', '$'=>'$%', '\\'=>'\\%']) . '}}/';
$str = preg_replace($pattern, $repValue, $str );
echo strtr($str, ['%%'=>'%', '$%'=>'$', '\\%'=>'\\']);

注意:如果$field 仅包含文字字符串(不是子模式),则不需要使用preg_replace。您可以改用str_replace,在这种情况下您无需替换任何内容。

【讨论】:

  • 没有。只是具体的 preg_quote()
  • @Deep: 不,preg_quote 仅适用于模式,不适合替换字符串(进行测试)
  • 欧...更换。对不起。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 2016-01-20
  • 1970-01-01
  • 2012-08-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2015-05-19
相关资源
最近更新 更多