python可以处理任何字符编码文本对吗_使用python解决文本文件中的字符串编码问题...

你必须做出假设

如果你不能对你将要遇到的信件做出假设,你可能就有麻烦了。因此,在我们的文档中,我们可以合理地假设挪威字母A-Å。没有什么神奇的工具可以自动更正您遇到的每个文档。在

因此,在这个域中,我们知道一个文件可能包含å,其UTF-8 2字节表示0xc3 0xa5或{a1},Latin-1和{a3}将其表示为0xe5。一般来说,这个character lookup非常好,如果你发现自己在研究一个字符,它可能会成为一个很好的书签。在

示例挪威人

损坏的版本Ã¥

您可以在这个方便的debugging chart中找到这类问题的长列表。在

基本Python编码、解码

如果你知道到底是什么地方出了问题,这是最简单的方法把绳子打回原形。在our_broken_string = 'Ã¥'

broken_unicode = our_broken_string.decode('UTF-8')

print broken_unicode # u'\xc3\xa5' yikes -> two different unicode characters

down_converted_string = broken_unicode.encode('LATIN-1')

print down_converted_string # '\xc3\xa5' those are the right bytes

correct_unicode = down_converted_string.decode('UTF-8')

print correct_unicode # u'\xe5' correct unicode value

文件

在处理文档时,可以做出一些相对较好的假设。单词、空格和行。即使文档是XML,您仍然可以将其视为单词,而不必太担心标记,或者如果单词确实是单词,则只需要能找到的最小单元。我们还可以假设,如果文件有文本编码问题,它可能也有行尾问题,这取决于有多少不同的操作系统损坏了该文件。我将在行尾中断rstrip,并使用print将数组重新组合到StringIO文件句柄。在

在保留空白时,通过一个漂亮的print函数运行XML文档可能很诱人,但是您不应该这样做,我们只想在不改变任何其他内容的情况下更正小文本单元的编码。一个好的起点是看看是否可以逐行逐字地阅读文档,而不是在任意的字节块中,而忽略您正在处理的是XML。在

在这里,我利用这样一个事实:如果文本超出UTF-8的范围,那么您将得到unicodedecoderrors,然后尝试使用拉丁语-1。这在这个文件中起作用了。在

^{pr2}$

处理Mojibake

如果你的问题是真的Mojibake,比如一个错误的文件名。您可以使用FTFY尝试试探性地更正您的问题。同样,我会采取逐字逐句的方法来获得最佳效果。在import os

import sys

import ftfy

import unicodedata

if __name__ == '__main__':

path = sys.argv[1]

file_system_encoding = sys.getfilesystemencoding()

unicode_path = path.decode(file_system_encoding)

for root, dirs, files in os.walk(unicode_path):

for f in files:

comparable_original_filename = unicodedata.normalize('NFC', f)

comparable_new_filename = ftfy.fix_text(f, normalization='NFC')

if comparable_original_filename != comparable_new_filename:

original_path = os.path.join(root, f)

new_path = os.path.join(root, comparable_new_filename)

print "Renaming:" + original_path + " to:" + new_path

os.rename(original_path, new_path)

这通过目录更正了很多更丑陋的错误,其中å被拼成了{}。这是什么?大写字母A+COMBINING LETTER TILDE0xcc 0x83是使用unicode equivalence表示Ã的几种方法之一。这确实是FTFY的一项工作,因为它实际上将执行一个启发式的任务,并解决这些类型的问题。在

用于比较和文件系统的Unicode规范化

另一种方法是使用unicode的规范化来获得正确的字节。在import unicodedata

a_combining_tilde = 'A\xcc\x83'

# Assume: Expecting UTF-8

unicode_version = a_combining_tilde.decode('UTF-8') # u'A\u0303' and this cannot be converted to LATIN-1 and get Ã

normalized = unicodedata.normalize('NFC', unicode_version) # u'\c3'

broken_but_better = normalized.encode('UTF-8') # '\xc3\x83` correct UTF-8 bytes for Ã.

总之,如果将其作为UTF-8编码的字符串A\xcc\x83\xc2\xa5,对其进行规范化,然后向下转换为拉丁语-1字符串,然后再返回到UTF-8,您将获得正确的unicode。在

你需要注意操作系统是如何编码文件名的。您可以通过以下方式检索该信息:file_system_encoding = sys.getfilesystemencoding()

假设file_system_encoding是{},对吗?然后比较两个看起来完全相同的unicode字符串,结果它们不相等!FTFY,默认规格化为NFC,HFS规范化为NFD的旧版本。因此,仅仅知道编码是相同的是不够的,你必须用同样的方式规范化比较才能有效。在Windows NTFS存储unicode而不进行规范化。在

Linux存储unicode而不进行规范化。在

machfs使用专有HFD规范化存储UTF-8。在

在节点.js有关于dealing with different filesystems的好指南。总之,规范化是为了比较,不要任意地重新规范化文件名。在

最后说明

谎言、该死的谎言和XML声明

在XML d中文档您将得到这样的东西,它应该通知XML解析器有关文本编码的信息。在<?xml version="1.0" encoding="ISO-8859-1"?>

如果你看到了这一点,在被证明是真的之前,它应该被视为谎言。在将此文档交给XML解析器之前,您需要验证和处理编码问题,并且需要更正声明。在

谎言,该死的谎言和BOM标记

字节顺序标记听起来是个不错的主意,但就像它们的XML声明一样,它们是文件编码情况的完全不可靠的指示器。Within UTF-8, BOMs are NOT recommended并且对于字节顺序没有意义。它们唯一的值是指示某些东西是用UTF-8编码的。但是,考虑到文本编码的问题,默认值是而且应该是预期的UTF-8。在

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值