Php 如何将unicode代码点转换为十六进制HTML实体?

Php 如何将unicode代码点转换为十六进制HTML实体?,php,html,unicode,Php,Html,Unicode,我有一个数据文件(确切地说是一个苹果plist),它有\U00e8和\U2019。我需要使用PHP将它们转换为有效的十六进制 我现在正在做的是一长串: $fileContents = str_replace("\U00e8", "è", $fileContents); $fileContents = str_replace("\U2019", "’", $fileContents); 这显然是可怕的。我可以使用正则表达式将\U和所有尾随0s转换为&x

我有一个数据文件(确切地说是一个苹果plist),它有
\U00e8
\U2019
。我需要使用PHP将它们转换为有效的十六进制

我现在正在做的是一长串:

 $fileContents = str_replace("\U00e8", "è", $fileContents);
 $fileContents = str_replace("\U2019", "’", $fileContents);
这显然是可怕的。我可以使用正则表达式将
\U
和所有尾随
0s
转换为
&x
,然后继续尾随
,但这似乎也很严厉

是否有一种干净、简单的方法来获取字符串,并将所有unicode代码点替换为HTML实体?

您可以使用:

测试RE:

PS> 'some \U00e8 string with \U2019 embedded Unicode' -replace '\\U0*([0-9a-f]{1,5})','&#x$1;'
some è string with ’ embedded Unicode

这是一个正确的答案,它处理了这样一个事实,即这些是代码单元,而不是代码点,并且允许取消编码补充字符

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;
}
函数unec\u utf16\u code\u单位($string){
/*首先寻找可能的代理项对*/
$string=preg\u replace\u回调(
“/\\\U(D[89ab][0-9a-f]{2})\\\U(D[c-f][0-9a-f]{2})/i”,
函数($matches){
$hi_surr=hexdec($matches[1]);
$lou surr=hexdec($matches[2]);

$scalar=(0x10000+($hi_surr&0x3FF)PCRE正则表达式非常快速和安全;我会使用它们。(其他官方解决方案可能也会使用正则表达式。或者使用查找表,这就是您现在拥有的。)根据,这些转义序列表示UTF-16代码单元,而不是Unicode代码点。这意味着您可能必须组合两个连续的代码单元(如果它们形成代理项对)以形成HTML实体。似乎是正则表达式的一个明确用例。@Tina Marie,如果您需要更多的plist处理,请查看。
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;
}