如何将"\ u00ed"等Unicode转义序列解码为正确的UTF-8编码字符?

Doc*_*ero 88 php unicode escaping utf-8 decoding

PHP中是否有一个函数可以解码像" \u00ed"到" í" 这样的Unicode转义序列以及所有其他类似的事件?

我在这里发现了类似的问题,但似乎没有用.

Gum*_*mbo 157

试试这个:

$str = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/', function ($match) {
    return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UCS-2BE');
}, $str);
Run Code Online (Sandbox Code Playgroud)

如果它是基于UTF-16的C/C++/Java/Json风格:

$str = preg_replace_callback('/\\\\u([0-9a-fA-F]{4})/', function ($match) {
    return mb_convert_encoding(pack('H*', $match[1]), 'UTF-8', 'UTF-16BE');
}, $str);
Run Code Online (Sandbox Code Playgroud)

  • 此功能无法处理补充字符,因为它们无法在UCS-2中表示. (7认同)
  • 我在这里找到了自己的方式,因为我在输出中使用了 \u00ed,但我正在使用 json_encode() 查看输出,有趣的是默认的 json_encode() 会破坏输出,所以使用 json_encode($theDict,JSON_PRETTY_PRINT | JSON_UNESCAPED_UNICODE); (3认同)
  • @Docstero:正则表达式将匹配任何序列的`\ u`后跟四个十六进制数字. (2认同)
  • @gumbo你如何打电话或使用这个功能? (2认同)

小智 65

print_r(json_decode('{"t":"\u00ed"}')); // -> stdClass Object ( [t] => í )
Run Code Online (Sandbox Code Playgroud)

  • 它甚至不需要对象包装器:`json_decode('"'.$ text.'"')` (37认同)
  • 谢谢.**这似乎是STANDARD WAY**,而不是接受了答案. (3认同)
  • @deceze 你应该包括`$text` 可以包含双引号的事实。所以修改后的版本是:`json_decode('"'.str_replace('"', '\\"', $text).'"')`。谢谢你的帮助 :-) (2认同)

Rab*_*ong 11

PHP 7+

从PHP 7开始,您可以使用Unicode代码点转义语法来执行此操作.

echo "\u{00ed}";输出í.

  • 谢谢!比其他答案简单得多 (2认同)

mas*_*tic 8

$str = '\u0063\u0061\u0074'.'\ud83d\ude38';
$str2 = '\u0063\u0061\u0074'.'\ud83d';

// U+1F638
var_dump(
    "cat\xF0\x9F\x98\xB8" === escape_sequence_decode($str),
    "cat\xEF\xBF\xBD" === escape_sequence_decode($str2)
);

function escape_sequence_decode($str) {

    // [U+D800 - U+DBFF][U+DC00 - U+DFFF]|[U+0000 - U+FFFF]
    $regex = '/\\\u([dD][89abAB][\da-fA-F]{2})\\\u([dD][c-fC-F][\da-fA-F]{2})
              |\\\u([\da-fA-F]{4})/sx';

    return preg_replace_callback($regex, function($matches) {

        if (isset($matches[3])) {
            $cp = hexdec($matches[3]);
        } else {
            $lead = hexdec($matches[1]);
            $trail = hexdec($matches[2]);

            // http://unicode.org/faq/utf_bom.html#utf16-4
            $cp = ($lead << 10) + $trail + 0x10000 - (0xD800 << 10) - 0xDC00;
        }

        // https://tools.ietf.org/html/rfc3629#section-3
        // Characters between U+D800 and U+DFFF are not allowed in UTF-8
        if ($cp > 0xD7FF && 0xE000 > $cp) {
            $cp = 0xFFFD;
        }

        // https://github.com/php/php-src/blob/php-5.6.4/ext/standard/html.c#L471
        // php_utf32_utf8(unsigned char *buf, unsigned k)

        if ($cp < 0x80) {
            return chr($cp);
        } else if ($cp < 0xA0) {
            return chr(0xC0 | $cp >> 6).chr(0x80 | $cp & 0x3F);
        }

        return html_entity_decode('&#'.$cp.';');
    }, $str);
}
Run Code Online (Sandbox Code Playgroud)