Bizzare多字节preg_replace问题。它正在将我的数据改为笑脸!

时间:2011-07-10 18:48:17

标签: php preg-replace

在Windows上使用PHP 5.3.1。

我只是想在数字和字母之间添加空格,但PHP正在破坏我的数据!

$text = "TUES:8:30AM-5:00PMTHURS:8:30AM-5:00PMSAT:8:00AM-1:00PM";
echo preg_replace("/([0-9]+)([A-Z]+)/","\1 \2",$text);
> TUES:8:☺ ☻AM-5:☺ ☻PMTHURS:8:☺ ☻AM-5:☺ ☻PMSAT:8:☺ ☻AM-1:☺ ☻PM

我的文件类型为ANSI,源中没有unicode。

这里有什么乐趣?

3 个答案:

答案 0 :(得分:5)

尝试使用$是你的反向引用指标,而不是'\':

echo preg_replace("/(\d)(\w)/","$1 $2",$text);

我打赌\1正在被翻译成时髦的东西......注意奇怪的字符在分钟输入为'30'和'00'之间不会改变

php manual表示您应该双重撤销反向引用,或使用$(如果您使用的是4.04或更新版本)

答案 1 :(得分:2)

在用双引号分隔的字符串中使用它们时应该使用双反斜杠:

echo preg_replace("/(\d)(\w)/","\\1 \\2",$text);

答案 2 :(得分:2)

\1\2正在被PHP转义,并被解释为ASCII代码1和2,在大多数标准Windows字体中显示为您看到的两个笑脸(当我在我的Linux机器上运行相同的程序,我得到字符代码符号0001和0002而不是笑脸。)

如果您想实际使用正则表达式替换符号,则需要执行以下两项操作之一:

  1. 对正则表达式字符串使用单引号,以便斜杠不会被PHP用作转义字符:

    preg_replace('/(\d)(\w)/','\1 \2',$text);
    
  2. 使用双引号,但转义斜杠:

    preg_replace("/(\\d)(\\w)/","\\1 \\2",$text);
    
  3. 我建议单引号解决方案,因为它更容易阅读。

    请注意,使用双引号时,PHP转义将始终优先于正则表达式转义。这可能会影响您的正则表达式模式和替换字符串。无论如何,许多PHP转义字符对于正则表达式都是相同的 - 例如,\n在正则表达式模式中的工作方式相同,无论它是由PHP还是由正则表达式转义。但是有些东西的效果不一样 - 正如你所发现的那样 - 所以你需要小心。