创建一个文件test.php
并运行下面的代码(使用 UTF-8 字符集保存文件)。
echo preg_replace("/./","X","Á");
您将得到XX
(它应该只返回一个X
,但这是第一个错误)。PHP 在这里使用多字节做了一些奇怪的事情。
现在运行此代码:
echo preg_replace("/.$/","X","Á");
您将得到�X
。这与上面的错误有关,但由于某种原因,第一个字符被损坏。
无论如何,有没有简单的方法可以解决这个问题?我当前的正则表达式比上面的要复杂得多,当然上面的是没用的,但这是重现错误的最低限度。
发生此问题的原因是该
preg_replace
函数将输入字符串中的每个字符替换为"X"
。该字符"Á"
在 PHP 中被视为多字节字符,这意味着它在内存中存储为多个字节(或部分)。当
preg_replace
使用模式时"/./"
,它会分别匹配每个字节,而不是整个"Á"
字符。因此,它不是"Á"
用一个替换,而是用 替换的"X"
每个部分(字节),从而得到。"Á"
"X"
"XX"
要修复此问题,您应该使用适用于多字节字符的正则表达式。像这样
解释:添加
u
修饰符告诉 PHP 将字符串视为 UTF-8。您的第二个代码的问题与第一个代码类似。以下是对此的修复。
在线执行:https://3v4l.org/RLYma