正确处理php中的转义unicode字符

时间:2013-09-05 09:54:06

标签: php unicode

使用php我解析包含

等unicode字符的文本文件

只需读入文件而不进行任何进一步的编码/解码,解析笑脸,然后json_encoded,输出为\u00f0\u009f\u0098\u008d

javascript文件获取.json数据并输出4个转义字符ð

查看一个unicode表,该符号被称为“用心形眼睛微笑”并且具有unicode编号U+1F60D(128525)

有没有办法将4个代码单元转换为unicodenumber或理想情况下转换为正确的html编码方式,在本例中为😍

看着转换,utf 8代码单元看起来很相似(F0 9F 98 8D 0A 0A),但我无法重现我得到的4个转义单位,所以我甚至不知道我在看什么< / p>

更新:我犯了一个错误并编辑了第二段:\u00f0\u009f\u0098\u008d已经是json_encode()的结果;

这是从文件中读取数据的基本功能,查看笑脸是“硬编码”的来源,所以你实际看到它

function readLocalFile() {
  $file_html = fopen('output.html', "r");
  $html = "";

  while(!feof($file_html)) {
    $html .= fgets($file_html);
  }

  fclose($file_html);

  // here I use regex to filter for specific tags, the result is an array
  $cleanData = parseData($html);

  saveToFile(json_encode($cleanData)); 
}

我刚创建了一个只有作为内容的dummy.html,这会返回正确的结果\ud83d\ude0d,在整个数据的上下文中,它仍然如上所述被破坏,很奇怪

我必须查看数据保存到output.html的方式,这就是问题所在。我一直在寻找问题的错误部分,噢哦!

最后更新:终于找到了错误。它是在parseData-function中,loadHTML以某种方式将内容弄乱了,在这里找到了解决方案: PHP DOMDocument loadHTML not encoding UTF-8 correctly

2 个答案:

答案 0 :(得分:1)

我的问题让我感到困惑的是\u00f0\u009f\u0098\u008d序列。它听起来不像任何标准化。

正如你所写,这是关于 Unicode Character 'SMILING FACE WITH HEART-SHAPED EYES' (U+1F60D)。您提供的基于\u的表示法似乎表明这将是Javascript / JSON编码的unicode字符。所以让我们稍微回顾一下:

  • JSON使用UTF-16代理项对不在基本多语言平面中的任何内容(U + 0000到U + FFFF)。
  • U + 1F60D在基本多语言窗格中
  • 因此UTF-16编码为0xD83D 0xDE0D
  • 这不是你所拥有的
  • 它的UTF-8编码是xF0 0x9F 0x98 0x8D
  • 这看起来像你滥用的东西。

在快速分析之后,答案如下:如果您可以认为所有\u????序列都被误用于编码UTF-8二进制序列,那么您需要做的就是挂钩每个序列,将最后一个十六进制数字中编码的字符组合在一起(最后是位置5 + 6 /索引4 + 5)并将它们组合在一起。

由于这看起来很糟糕,我不建议在这里使用完整源代码,因为我不想特别支持这种做法 - 你需要在编码中修复它 - 但是你可以找到{{的答案中概述的代码3}}

因此修复包含错误\u的输入字符串(u代表unicode,但在你的情况下不是因为那些暗示UTF-16 不是二进制八位字节)。你需要了解那些错误的\u序列的引入位置,你的问题并不清楚。

答案 1 :(得分:0)

你所拥有的是将UTF-8数据解码为ISO-8859-1(latin1)到Unicode,然后进行JSON编码。如果你:

  1. 将JSON解码为Unicode。
  2. 使用latin-1编码为字节。
  3. 使用UTF-8解码为Unicode。
  4. 这应该给你正确的角色。我不做PHP,但这是一个Python证明:

    >>> '\u00f0\u009f\u0098\u008d'.encode('latin1').decode('utf8')
    '\U0001f60d'
    >>> import unicodedata as ud
    >>> ud.name('\U0001f60d')
    'SMILING FACE WITH HEART-SHAPED EYES'
    

    数据首先出现乱码的原因可能是HTML实际上是UTF-8编码的,但错误地声明了ISO-8859-1或Windows-1252。