相同的字符,不同的长度和字节

时间:2018-01-31 08:03:01

标签: python unicode character-encoding

从韩国网站下载文件,通常文件名被错误编码/解码,最终混乱不堪。我发现用'iso-8859-1'编码并用'euc-kr'解码,我可以解决这个问题。但是,我遇到了一个新问题,其中同样的角色实际上是不同的。查看下面的Python shell:

>>> first_string = 'â'
>>> second_string = 'â'
>>> len(first_string)
1
>>> len(second_string)
2
>>> list(first_string)
['â']
>>> list(second_string)
['a', '̂']
>>>

可以使用'iso-8859-1'编码第一个字符串。后者不是。所以问题是:

  1. 这两个字符串有什么区别?
  2. 为什么来自同一网站的下载具有不同格式的相同字符? (如果这就是差异。)
  3. 我该如何解决这个问题? (例如,将second_string转换为first_string
  4. 的相似度

    谢谢。

2 个答案:

答案 0 :(得分:2)

  1. 一个简单的方法来确切地找出一个角色是问vim。将光标放在字符上并键入ga以获取信息。

    第一个是:

    <â> 226, Hex 00e2, Octal 342
    

    第二个:

    <a>  97,  Hex 61,  Octal 141 < ̂> 770, Hex 0302, Octal 1402
    

    换句话说,第一个是complete "a with circumflex" character,第二个是regular a,后跟circumflex combining character

  2. 询问网站运营商。我们怎么知道?!

  3. 您需要将字符组合成常规字符的内容。例如,谷歌搜索产生了this question

    正如你在评论中指出的那样,正如另一个答案所指出的那样,在Python中你可以使用unicodedata.normalize和'NFC'作为表格。

答案 1 :(得分:2)

  1. Unicode中的重音和分音符有不同的表示形式。代码点U + 00E2上有一个字符,COMBINING CIRCUMFLEX ACCENT(U + 0302)是由Python 2.7中的u'a\u0302'创建的。它由两个字符组成:'a'和抑扬符。

  2. 不同表示的一个可能原因是,网站的创建者已经复制了来自不同来源的文本。例如,PDF文档通常使用两个复合字符显示变音符号和重音符号,而在键盘上键入这些字符通常会产生单个字符表示。

  3. 您最多使用unicodedata.normalize将组合字符转换为单个字符,例如:

    from unicodedata import normalize
    
    s = u'a\u0302'
    print s, len(s), len(normalize("NFC", s))
    
  4. 将输出â 2 1