在我的字符串中,我有utf-8不间断空格(0xc2a0),我想用其他东西替换它。
当我使用
时$str=preg_replace('~\xc2\xa0~', 'X', $str);
它运作正常。
但是当我使用
时$str=preg_replace('~\x{C2A0}~siu', 'W', $str);
找不到(并替换)不间断的空间。
为什么呢?第二个正则表达式有什么问题?
格式\x{C2A0}
是正确的,我还使用了u
标记。
答案 0 :(得分:53)
实际上PHP中关于转义序列的文档是错误的。使用\xc2\xa0
语法时,它会搜索UTF-8字符。但是使用\x{c2a0}
语法,它会尝试将Unicode序列转换为UTF-8编码字符。
非中断空格为U+00A0
(Unicode),但在UTF-8中编码为C2A0
。因此,如果您尝试使用模式~\x{00a0}~siu
,它将按预期工作。
答案 1 :(得分:12)
我已经对以前的答案进行了分析,以便人们可以复制/粘贴以下代码来选择他们喜欢的方法:
$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>';
答案 2 :(得分:3)
在我看来,这两个代码做了不同的事情:第一个\xc2\xa0
将替换两个字符\xc2
和\xa0
。
在UTF-8编码中,这恰好是U+00A0
的代码点。
\x{00A0}
是否有效?这应该是\xc2\xa0
的表示。
答案 3 :(得分:1)
我没有使用此变体~\x{c2a0}~siu
。
瓦里安\x{00A0}
有效。我没有尝试过第二个选项,结果如下:
我尝试将其转换为十六进制,并将不间断空格0xC2 0xA0 (c2a0)
替换为空格0x20 (20)
。
代码:
$hex = bin2hex($item);
$_item = str_replace('c2a0', '20', $hex);
$item = hex2bin($_item);
答案 4 :(得分:0)
/ \ x {00A0} /,/ \ xC2 \ xA0 /和$ clean_hex2bin-str_replace-bin2hex工作无效。如果我把它打印到屏幕上,这一切都很好,但是如果我试图将它保存到文件中,那么该文件将是空白的!
我最终使用了iconv('UTF-8','ISO-8859-1 // IGNORE',$ str);