我正在尝试从python脚本将unicode文本输出到RTF文件。对于背景,Wikipedia说
对于Unicode转义,使用控制字\ u,然后使用16位带符号十进制整数,给出Unicode UTF-16代码单元号。为了没有Unicode支持的程序的好处,必须在指定的代码页中跟随此字符的最近表示。例如,\ u1576?将给出阿拉伯字母bā'ب,指明没有Unicode支持的旧程序应该将其作为问号呈现。
还有this question on outputting RTF from Java和this one on doing so in C#。
然而,我无法弄清楚的是如何将Python的unicode代码点输出为“带有Unicode UTF-16代码单元号的16位带符号十进制整数”。我试过这个:
for char in unicode_string:
print '\\' + 'u' + ord(char) + '?',
但输出只在文字处理器中打开时呈现为乱码;问题似乎是它不是UTF-16代码。但不知道如何得到它;虽然可以用utf-16编码,但是如何获得代码?
顺便提一句PyRTF不支持unicode(它被列为“todo”),虽然pyrtf-NG应该这样做,但该项目似乎没有维护并且文档很少,所以我对使用它很谨慎在准生产系统中。
编辑:我的错误。上面的代码中有两个错误 - 正如Wobble所指出的那样,字符串必须是一个unicode字符串,而不是已编码的字符串,而上面的代码产生一个结果,字符之间有空格。正确的代码是:
convertstring=""
for char in unicode(<my_encoded_string>,'utf-8'):
convertstring = convertstring + '\\' + 'u' + str(ord(char)) + '?'
这很好,至少对于OpenOffice。我将此作为其他人的参考 (以下讨论后进一步纠正了一个错误。)
答案 0 :(得分:3)
根据您最新编辑中的信息,我认为此功能可以正常使用。除了下面的改进版本。
def rtf_encode(unistr):
return ''.join([c if ord(c) < 128 else u'\\u' + unicode(ord(c)) + u'?' for c in unistr])
>>> test_unicode = u'\xa92012'
>>> print test_unicode
©2012
>>> test_utf8 = test_unicode.encode('utf-8')
>>> print test_utf8
©2012
>>> print rtf_encode(test_utf8.decode('utf-8'))
\u169?2012
这是另一个版本,有点分解,更容易理解。我还在返回一个ASCII字符串时保持一致,而不是保留Unicode并在join
上插入它。它还包含基于评论的修复程序。
def rtf_encode_char(unichar):
code = ord(unichar)
if code < 128:
return str(unichar)
return '\\u' + str(code if code <= 32767 else code-65536) + '?'
def rtf_encode(unistr):
return ''.join(rtf_encode_char(c) for c in unistr)
答案 1 :(得分:1)
Mark Ransom的回答并不正确,因为它不会正确编码U + 7fff上的代码点,也不会按照RTF标准的建议转义低于0x20的字符。
我创建了一个简单的模块,将python unicode编码为名为rtfunicode
和wrote about the subject on my blog的RTF控制代码。
总之,我的方法使用正则表达式将正确的代码点映射到适合包含在PyRTF或pyrtf-ng中的RTF控制代码。