如何将这种奇怪的字符串解码为UTF-8?(PHP)

Rel*_*lla 4 php encode decode utf-8

所以我有%u041E%u043B%u0435%u0433%20%u042F%u043A如何将它保存为真正的UTF-8或(对我来说更好的HTML实体)?

bob*_*nce 10

这是JavaScript escape()格式.它类似于URL编码但不兼容.完全使用它通常是一个错误.

最好的办法是更改生成它的脚本,改为使用正确的URL-encoding(encodeURIComponent()).然后,您可以使用urldecode服务器端的任何其他常规URL解码功能对其进行解码.

如果您绝对必须以这种非标准格式交换数据,则必须为其编写自定义解码器.这是一个利用HTML字符引用解码器的快速黑客:

function jsunescape($s) {
    $s= preg_replace('/%u(....)/', '&#x$1;', $s);
    $s= preg_replace('/%(..)/', '&#x$1;', $s);
    return html_entity_decode($s, ENT_COMPAT, 'utf-8');
}
Run Code Online (Sandbox Code Playgroud)

这将返回原始UTF-8字节字符串.如果你真的想要HTML格式引用,Ру...那么请不要html_entity_decode打电话.但通常你不这样做.最好保持字符串的原始格式,直到它们需要转义为最终输出 - 最好不要用字符引用替换非ASCII字符,除非你真的需要.

什么如果像这样的一些字符串将来找我'%CE%EB%E5%E3 +%DF%EA%F3%F8%EA%E8%ED'

这是URL格式编码,与escape()格式不直接兼容.虽然URL编码的2位字节转义与疯狂escape格式化的4位代码单元转义不同,但该字符+不明确.它可能意味着加号(如果字符串来自escape)或空格(如果它来自浏览器表单提交).没有办法分辨出它是什么.这是不使用的另一个原因escape().

除此之外; 如果该字符串的字符集是UTF-8然后是,则上述函数可以正常,将URL编码的字节和疯狂escape()格式的Unicode字符转换为原始的UTF-8字节.

然而它实际上似乎是代码页1251(Windows俄语).你真的想在cp1251中处理所有的字符串吗?如果是这样,你将不得不改变它以使它将四位数的转义编码为不同的字符集.这很麻烦:

function url_or_maybe_jsescape_decode($s, $charset, $isform) {
    if ($isform)
        $s= str_replace('+', ' ', $s);
    $s= preg_replace('/%u(....)/', '&#x$1;', $s);
    $s= preg_replace('/%(..)/', '&!#x$1;', $s);
    $s= html_entity_decode($s, ENT_COMPAT, $charset);
    $s= str_replace('&!', '&', $s);
    $s= html_entity_decode($s, ENT_COMPAT, 'utf-8');
    return $s;
}

echo url_or_maybe_jsescape_decode('%CE%EB%E5%E3+%DF%EA%F3%F8%EA%E8%ED', 'cp1251', TRUE);
Run Code Online (Sandbox Code Playgroud)

我强烈建议:

  1. 修复Flash文件,使其使用正确encodeURIComponent而不是escape,因此您可以使用标准的URL解码器而不是这个丑陋的黑客.

  2. 在您的应用程序中使用UTF-8,因此您可以支持除俄语之外的其他语言,并且您不必担心提交的表单的输入编码会发生变化.

(所有不是UTF-8的编码很糟糕,这是科学证明的事实!)