如何将CP949 RTF转换为UTF-8编码的RTF?

时间:2013-12-24 02:36:33

标签: python encoding utf-8 rtf

我想编写一个python脚本,将文件编码从cp949转换为utf8。该文件在cp949中进行了原始编码。 我的脚本如下:

cpstr = open('terms.rtf').read()  
utfstr = cpstr.decode('cp949').encode('utf-8')  
tmp  = open('terms_utf.rtf', 'w')  
tmp.write(utfstr)  
tmp.close()

但这不会像我想的那样改变编码。

2 个答案:

答案 0 :(得分:4)

有三种RTF,我不知道你有哪种。 可以通过在纯文本编辑器中打开文件,或者仅使用less / more / cat / type /将它打印到您的终端。


首先,简单的案例:明文RTF。

纯文本RTF文件以{\rtf开头,其中的所有文本都是(正如您所期望的)纯文本 - 尽管有时文本的运行会被分解为带格式化命令的单独运行 - 以\开头 - 在它们之间。由于所有格式化命令都是纯ASCII,如果将明文RTF从一个字符集转换为另一个字符集(只要两者都是ASCII的超集,如同cp949和utf-8都是),它应该可以正常工作。

但是,该文件可能还有一个格式化命令,用于指定写入的字符集。此命令类似于\ansicpg949。当像Wordpad这样的RTF编辑器打开你的文件时,它会把你所有漂亮的UTF-8数据解释为cp949数据,除非你修复它,否则就会把它搞砸了。

解决这个问题的最简单方法是找出你的编辑器想要为UTF-8文件放置什么字符集。也许它是\ansicpg65001,也许它是\utf8,也许它是完全不同的东西。因此,只需将一个简单文件保存为UTF-8 RTF,然后以纯文本格式查看 it ,并查看其代替\ansicpg949的内容,并替换文件中的字符串正确的那一个。 (请注意,代码页65001不是真的 UTF-8,但是它很接近,并且很多Microsoft代码假设它们是相同的......)

此外,一些RTF编辑器(如Apple的TextEdit)将转义任何非ASCII字符(因此,例如,é存储为\'e9),因此无需转换。

最后,Office Open XML包含一个名为RTF的XML规范,但实际上并不是同一个东西。我相信很多RTF编辑都可以解决这个问题。幸运的是,您可以像使用纯文本RTF一样对待它 - 所有XML标记都具有纯ASCII名称。


几乎同样简单的情况是压缩的纯文本RTF。这是同样的事情,但我相信zlib会压缩。或者它实际上可以是.zip存档中的RTFD(可以是文本RTF以及单独文件中的图像和其他内容,或者格式运行存储在单独文件中的实际纯文本)。无论如何,如果您有其中之一,大多数Unix系统上的file命令应该能够将其检测为“压缩RTF”,此时我们可以找出具体格式是什么并对其进行解压缩,然后您可以将其编辑为纯文本RTF(或RTFD)。

毋庸置疑,如果你不首先解压缩,你就不会在文件中看到任何熟悉的文本 - 你可能很容易破坏它,因此它无法解压缩或解压缩为垃圾,通过将任意字节更改为不同的字节。


最后,硬案例:二进制RTF。

其中最早的版本采用无证版本,尽管它们是反向工程的。后期版本是公共规格。 Wikipedia有指向规范的链接。如果你想手动解析它,你可以,但它将是大量的代码,你将不得不自己编写。

更好的解决方案是使用可以将RTF(包括二进制RTF)转换为其他格式的one of the many libraries on PyPI,然后您可以轻松编辑这些格式。

答案 1 :(得分:-1)

import codecs
cpstr = codecs.open('terms.rtf','r','cp949').read()
u = cpstr.encode('cp949').decode('utf-8')
tmp  = open('terms_utf.rtf', 'w') 
tmp.write(u)  
tmp.close()