不间断的 utf-8 0xc2a0空间和preg_replace奇怪的行为

2022-08-30 13:05:14

在我的字符串中,我有utf-8不间断空格(0xc2a0),我想用其他东西替换它。

当我使用时

$str=preg_replace('~\xc2\xa0~', 'X', $str);

它工作正常。

但是当我使用时

$str=preg_replace('~\x{C2A0}~siu', 'W', $str);

未找到(和替换)不换行空格。

为什么?第二个正则表达式有什么问题?

格式是正确的,我也用了标志。\x{C2A0}u


答案 1

实际上,PHP中关于转义序列的文档是错误的。使用语法时,它会搜索 UTF-8 字符。但是使用语法,它会尝试将 Unicode 序列转换为 UTF-8 编码字符。\xc2\xa0\x{c2a0}

不换行空格是 (Unicode),但编码为 UTF-8。因此,如果您尝试使用该模式,它将按预期工作。U+00A0C2A0~\x{00a0}~siu


答案 2

我已经收集了以前的答案,因此人们可以复制/粘贴以下代码以选择自己喜欢的方法:

$some_text_with_non_breaking_spaces = "some text with 2 non breaking spaces at the beginning";
echo 'Qty non-breaking space : ' . substr_count($some_text_with_non_breaking_spaces, "\xc2\xa0") . '<br>';
echo $some_text_with_non_breaking_spaces . '<br>';

# Method 1 : regular expression
$clean_text = preg_replace('~\x{00a0}~siu', ' ', $some_text_with_non_breaking_spaces);

# Method 2 : convert to bin -> replace -> convert to hex
$clean_text = hex2bin(str_replace('c2a0', '20', bin2hex($some_text_with_non_breaking_spaces)));

# Method 3 : my favorite
$clean_text = str_replace("\xc2\xa0", " ", $some_text_with_non_breaking_spaces);

echo 'Qty non-breaking space : ' . substr_count($clean_text, "\xc2\xa0"). '<br>';
echo $clean_text . '<br>';

推荐