无法显示的case

从网上API获取到一个json文件,里面含有中文,从命令行中获取:
curl https://api.rhilip.info/tool/movieinfo/gen\?url\=https://movie.douban.com/subject/26709258/\?from\=showing

发现不太对劲,为什么都是使用ASCII表示的UTF-8,赶紧转换一下编码(貌似这里有点问题)
curl https://api.rhilip.info/tool/movieinfo/gen\?url\=https://movie.douban.com/subject/26709258/\?from\=showing | iconv -f ASCII -t UTF-8
但是结果还是相同的。

从文件二进制的角度看xd <filename>

底层的确是ASCII编码。

其实这里貌似牵涉到ASCII是UTF-8的一个子集,貌似解析成ASCII也是没有问题的。
Force encode from US-ASCII to UTF-8 (iconv)这个问题的回答中提出了应该是自带的file命令的错误解析文件编码的问题,具体如何解决还需要进一步查找。

能显示的case

  1. 使用Firefox来看json
  2. 使用Python自带的json.load来解析json

大佬们有什么办法可以提出来试试呀!

    这不是 iconv 工具能不能转的问题,而是你接收到的 JSON 的数据本身就是这样的格式~

    刚去翻了一下 JSON 的定义文档 RFC7159
    https://tools.ietf.org/html/rfc7159

    在第七节 Strings

    Any character may be escaped. If the character is in the Basic
    Multilingual Plane (U+0000 through U+FFFF), then it may be
    represented as a six-character sequence: a reverse solidus, followed
    by the lowercase letter u, followed by four hexadecimal digits that
    encode the character's code point. The hexadecimal letters A though
    F can be upper or lower case. So, for example, a string containing
    only a single reverse solidus character may be represented as
    "\u005C".

    也就是说,这就是符合标准的 JSON 格式,\u7f57 之类的就是这里说的 six-character sequence 了,既然都是6个字符,iconv 怎么转都不会有变化。

    另外:
    这个问题你表达的不太清晰,这里你可能混淆了表示字符的方式和存储、转义的问题
    ascii是一种编码字符的格式,unicode是一种编码字符的格式
    ascii 这种格式能编码的字符太少,然后各种语系又有不同的格式(GBK,big5之类),相互之间很多兼容问题,最后就有了一个统一的全球通行的 unicode
    然后,utf-8 是以一种变长的方式去保存 unicode,是其中一种手段,目标是在满足表示的同时,节约存储 ascii 字符的空间浪费

    感觉需要仔细梳理一下编码这块的坑,刚刚找到一篇文
    【编码】彻底弄懂ASCII、Unicode、UTF-8之间的关系 - 大唐西域都护 - 博客园

      用 xxd 可以从一个个 byte 的角度去看它的原始形态,减少判断方向失误的可能性,缩小问题范围~
      比如说,空格的 ASCII 的十六进制是 0x20,双引号是 0x22,一一对应。

      0x0001 符合标准的 JSON 格式,\u7f57 之类的就是这里说的 six-character sequence 了,既然都是6个字符,iconv 怎么转都不会有变化。

      的确是这样的,我大概也了解了JSON的RFC讲什么了。。。其实就是在原本定义的Unicode编码前面加上\u的前缀。

      (左边的文件)自定义文本文件(含ASCII与UTF-8)

      我在编辑器上面写入英文字母与空格,仿照(右边文件的)00000030写的四个空格加上对应的ASCII,事实证明其实就是获取的文本格式就是ASCII。
      而在00000020的位置,e7 bd 97中文在十六进制的UTF-8编码,后文进行了转换与验证。

      (右边的文件)获取的JSON文件

      相比较从网上获取到的JSON中编码的Unicode字符(\u7f57),UTF-8相对来说还是比较麻烦的。。。。

      Unicode转UTF-8方式

      UTF-8使用一至六个字节为每个字符编码(尽管如此,2003年11月UTF-8被RFC 3629重新规范,只能使用原来Unicode定义的区域,U+0000到U+10FFFF,也就是说最多四个字节):

      1. 128个US-ASCII字符只需一个字节编码(Unicode范围由U+0000至U+007F)。
      2. 带有附加符号的拉丁文、希腊文、西里尔字母、亚美尼亚语、希伯来文、阿拉伯文、叙利亚文及它拿字母则需要两个字节编码(Unicode范围由U+0080至U+07FF)。
      3. 其他基本多文种平面(BMP)中的字符(这包含了大部分常用字,如大部分的汉字)使用三个字节编码(Unicode范围由U+0800至U+FFFF)。
      4. 其他极少使用的Unicode 辅助平面的字符使用四至六字节编码(Unicode范围由U+10000至U+1FFFFF使用四字节,Unicode范围由U+200000至U+3FFFFFF使用五字节,Unicode范围由U+4000000至U+7FFFFFFF使用六字节)。

      UTF-8 的编码规则很简单,只有二条:
      1)对于单字节的符号,字节的第一位设为0,后面7位为这个符号的 Unicode 码。因此对于英语字母,UTF-8 编码和 ASCII 码是相同的。
      2)对于n字节的符号(n > 1),第一个字节的前n位都设为1,第n + 1位设为0,后面字节的前两位一律设为10。剩下的没有提及的二进制位,全部为这个符号的 Unicode 码。

      使用作为Unicode转为UTF-8的例子


      这里可以看到罗的Unicode编码为7F57,这个我们后面会用到。
      根据U+7F57所在的范围,这个字占用三个字节编码。
      三个字节编码的格式为:1110 XXXX 10XX XXXX 10XX XXXX
      再将7F57从后往前填入字节编码中,就变成了:1110 0111 1011 1101 1001 0111也就是E7 BD 97。对应到我们上文往文本文件中写入中文,在十六进制编码下是相同的。

      总结

      • Unicode是一种编码方式,负责给每一个字符独一无二的编码。
      • 传回来的文件没有问题,格式为JSON,它是按照JSON的RFC中定义的对Unicode编码的一种实现。即在原有的Unicode编码前面加上前缀\u
      • UTF-8是Unicode的一种另外一种实现,具体转换规则见上文。

      iwktd1220
      见小黑进!
      这只是一个打印的问题吧

      echo `curl https://api.rhilip.info/tool/movieinfo/gen\?url\=https://movie.douban.com/subject/26709258/\?from\=showing`


      还是自己撸py好(逃

        4 天 后

        Tover emmmmm,一会用电脑试试……真没想到echo有这个功能……

        5 年 后

        © 2018-2025 0xFFFF