奇怪的多字节preg_replace问题.它正在把我的数据变成笑脸


Bizzare multibyte preg_replace issue. It is changing my data to smily faces!

在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。

这里有什么好玩的?

尝试使用$作为您的背景参考指标,而不是''':

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

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

php手册说你应该双转义你的背景引用,或使用$(如果你使用的是4.04或更新的版本)

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

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

'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);
    

我建议使用单引号,因为这样更容易阅读。

请注意,使用双引号时,PHP转义总是优先于正则表达式转义。这可能会影响您的正则表达式模式和替换字符串。许多PHP转义字符对于regex都是一样的——例如,'n在regex模式中工作是一样的,不管它是由PHP转义还是由regex转义。但是,正如你所发现的,有一些是不一样的,所以你需要小心。