我有一个ISO-8859-1的文件(很确定)。我的MySQL数据库采用utf-8编码。这就是为什么我想在将文件作为查询发送之前将文件转换为UTF-8编码字符的原因。例如,首先我使用 file.txt 将 file.txt 的每一行重写为 file_new.txt 。
line = line.decode('ISO-8859-1').encode('utf-8')
然后我保存它。接下来,我创建一个MySQL连接并使用以下查询创建一个游标,以便以utf-8接收所有数据。
query = 'SET NAMES "utf8"'
cursor.execute(query)
在此之后,我重新打开 file_new.txt 并将每行输入MySQL。这是以MySQL utf-8编码获取表格的正确方法吗?或者我错过了任何关键部分?
现在接收这些数据。我也使用'SET NAMES "utf8""
。但是当我将标题内容类型设置为
header("Content-Type: text/html; charset=utf-8");
另一方面,当我设置
header("Content-Type: text/html; charset=ISO-8859-1");
它工作正常,但来自数据库的其他utf-8编码数据正在被扰乱。因此,我猜测来自 file.txt 的数据仍然没有被编码为utf-8。任何人都可以解释原因吗?
PS:在我读取每行之前,我替换了一个字符并将 file.txt 保存到 file.txt.tmp 。然后我读了这个文件来获取 file_new.txt 。我不知道它是否会对原始文件编码造成任何问题。
f1 = codecs.open(tsvpath, 'rb',encoding='iso-8859-1')
f2 = codecs.open(tsvpath + '.tmp', 'wb',encoding='utf8')
for line in f1:
f2.write(line.replace('\"', '\''))
f1.close()
f2.close()
在下面的示例中,我是utf-8编码的波斯数据,这是正确的,但其他非英语文本将出现在"问号"中。这正是我的问题。
示例:已删除。
答案 0 :(得分:1)
请改为尝试:
line = line.decode('ISO-8859-1').encode('utf-8-sig')
来自文档:
由于UTF-8是8位编码,因此不需要BOM和任何U + FEFF 解码后的字符串中的字符(即使它是第一个字符)是 被视为零宽度无空间。
没有外部信息,就无法可靠地确定 哪个编码用于编码字符串。每个charmap编码 可以解码任何随机字节序列。然而,这是不可能的 UTF-8,因为UTF-8字节序列具有不允许的结构 任意字节序列。增加可靠性 可以检测到UTF-8编码,微软发明了UTF-8的变种 (Python 2.5称其为“utf-8-sig”)用于其记事本程序:之前 任何Unicode字符都写入文件,UTF-8编码 BOM(看起来像字节序列:0xef,0xbb,0xbf)是 书面。因为任何charmap编码文件都不太可能 从这些字节值开始(例如映射到
)拉丁文小写字母I DIAERESIS RIGHT-POINTING DOUBLE ANGLE iso-8859-1中的报价标记反转问号,这增加了 可以正确猜测utf-8-sig编码的概率 从字节序列。所以这里没有使用BOM 确定用于生成字节序列的字节顺序,但是 一个有助于猜测编码的签名。关于编码 utf-8-sig编解码器将写入0xef,0xbb,0xbf作为前三个字节 到文件。在解码时,如果utf-8-sig将跳过这三个字节 显示为文件中的前三个字节。在UTF-8中,使用了 不鼓励使用BOM,一般应避免使用。
来源:https://docs.python.org/3.5/library/codecs.html
修改强>
样品:
"Hello World".encode('utf-8')
产生b'Hello World'
,"Hello World".encode('utf-8-sig')
产生b'\xef\xbb\xbfHello World'
突出显示文档:
编码时 utf-8-sig编解码器将写入0xef,0xbb,0xbf作为前三个字节 到文件。在解码时,如果utf-8-sig将跳过这三个字节 显示为文件中的前三个字节。
修改强> 在将文件转换为utf-8编码之前,我已经做了类似的功能。这是一个片段:
def convert_encoding(src, dst, unicode='utf-8-sig'):
return open(dst, 'w').write(open(src, 'rb').read().decode(unicode, 'ignore'))
根据您的示例,试试这个:
convert_encoding('file.txt.tmp', 'file_new.txt')
答案 1 :(得分:1)
欢迎来到unicode和windows的精彩世界。我发现这个网站非常有助于理解我的字符串http://www.i18nqa.com/debug/utf8-debug.html出了什么问题。您需要的另一件事是像HxD这样的十六进制编辑器。有很多地方可能出问题。例如,如果您正在文本编辑器中查看文件,它可能会尝试提供帮助,并默默地更改您的编码。
从原始数据开始,在HxD中查看并查看编码是什么。在Hxd中查看结果,看看是否正在进行更改。重复整个过程中的步骤。
如果没有完整的代码和示例数据,很难说问题出在哪里。我的猜测是你用二元文件上的单引号代替双引号是罪魁祸首。
答案 2 :(得分:0)
好吧,伙计们,所以我的编码是正确的。该文件正在根据需要编码为utf-8。所有的询问都是正确的。事实证明,阿拉伯语中的其他数据集符合ISO-8859-1标准。因此,其中只有一个在工作。无论我做了什么。
Hexeditors确实提供了帮助。但最后我只使用了崇高的文本来重新检查我的编码数据是否为utf-8。事实证明,python脚本和sublime编辑器做了同样的事情。所以代码很好。 :)
答案 3 :(得分:0)
您不需要进行任何显式编码或解码。 SET NAMES ...
应该匹配客户端编码(对于INSERTing
)或应该成为(对于SELECTing
)。
MySQL将在客户端编码和列CHARACTER SET
之间进行转换。