我有一个数据文件(确切地说是一个Apple plist),它有Unicode codepoints,例如\U00e8
和\U2019
。我需要使用PHP将它们转换为有效的十六进制HTML entities。
我现在正在做的是一长串:
$fileContents = str_replace("\U00e8", "è", $fileContents);
$fileContents = str_replace("\U2019", "’", $fileContents);
这显然是可怕的。我可以使用正则表达式将\U
和所有尾随0s
转换为&#x
,然后坚持尾随;
,但这似乎也很苛刻。
是否有一种干净,简单的方法来获取字符串,并将所有unicode代码点替换为HTML实体?
答案 0 :(得分:7)
这是一个正确的答案,它处理的是这些是代码单元,而不是代码点,并允许取消编码补充字符。
function unenc_utf16_code_units($string) {
/* go for possible surrogate pairs first */
$string = preg_replace_callback(
'/\\\\U(D[89ab][0-9a-f]{2})\\\\U(D[c-f][0-9a-f]{2})/i',
function ($matches) {
$hi_surr = hexdec($matches[1]);
$lo_surr = hexdec($matches[2]);
$scalar = (0x10000 + (($hi_surr & 0x3FF) << 10) |
($lo_surr & 0x3FF));
return "&#x" . dechex($scalar) . ";";
}, $string);
/* now the rest */
$string = preg_replace_callback('/\\\\U([0-9a-f]{4})/i',
function ($matches) {
//just to remove leading zeros
return "&#x" . dechex(hexdec($matches[1])) . ";";
}, $string);
return $string;
}
答案 1 :(得分:4)
您可以使用preg_replace
:
preg_replace('/\\\\U0*([0-9a-fA-F]{1,5})/', '&#x\1;', $fileContents);
测试RE:
PS> 'some \U00e8 string with \U2019 embedded Unicode' -replace '\\U0*([0-9a-f]{1,5})','&#x$1;'
some è string with ’ embedded Unicode