如何解码没有“\”的“Unicode”,如 u091cu0940u0935u0928

问题描述

我正在使用 facebook api 来捕捉潜在客户,

我正在获取 JSON,在将其作为文本保存到 DB 后我正在使用它。

{"created_time":"2020-12-23T04:57:39+0000","id":"1021093571702954","field_data": 
[{"name":"full_name","values":["u091cu0940u0935u0928 u091au094cu0939u093eu0928"]},{"name":"city","values":["delhi"]},{"name":"phone_number","values":["+919911152366"]},{"name":"email","values":["uiabhiu0040gmail.com"]},{"name":"zip_code","values":["110095"]}]}

对于电子邮件,我发现 u0040 代表“@”,所以我在 PHP 中使用了字符串替换,但现在的问题是我以这种格式获取了一些名称,我不知道如何对其进行解码。

解决方法

使用 intl 扩展(确保它是 installed,它可能就像在 php.ini 中取消注释并重新启动服务器一样简单):

function translateUnescapedUnicode(string $subject): string
{
    return preg_replace_callback('/u([0-9a-fA-F]{4})/',function ($match) {
        return IntlChar::chr(hexdec($match[1]));
    },$subject);
}

这里发生了什么:

  1. 我们正在捕获未转义的 unicode 序列(u 后跟 4 个十六进制字符)
  2. $match[0] 将有完整匹配 (uXXXX),而 $match[1] 将只有我们的捕获组 (([0-9a-fA-F]{4})) - 十六进制字符
  3. 我们使用 hexdec 将十六进制值转换为十进制值
  4. 我们将十进制值提供给每个 documentationIntlChar::chr

返回包含由 Unicode 代码点值指定的字符的字符串。

在您的 JSON 上测试它:

$decodedJson = json_decode($json,true);
foreach ($decodedJson['field_data'] as $fieldData) {
    var_dump(translateUnescapedUnicode($fieldData['values'][0]));
}

将产生以下内容:

string(28) "जीवन चौहान"
string(5) "delhi"
string(13) "+919911152366"
string(16) "[email protected]"
string(6) "110095"

所以你可以在这里看到它保留了没有任何 unicode 字符的常规字符串。