2
4

2 回答 2

5

RTF 标准使用 UTF-16,但形状适合 RTF 命令序列格式。记录在http://en.wikipedia.org/wiki/Rich_Text_Format#Character_encoding。不幸的是,pyRTF 不会为您进行任何编码;处理这个问题已经在项目的 TODO 上,但显然他们在放弃图书馆之前从来没有这样做过。

这是基于我最近在一个项目中使用的代码。我现在rtfunicode在 PyPI 上发布了它,支持 Python 2 和 3;python 2版本:

import codecs
import re

_charescape = re.compile(u'([\x00-\x1f\\\\{}\x80-\uffff])')
def _replace(match):
    codepoint = ord(match.group(1))
    # Convert codepoint into a signed integer, insert into escape sequence
    return '\\u%s?' % (codepoint if codepoint < 32768 else codepoint - 65536)    


def rtfunicode_encode(text, errors):
    # Encode to RTF \uDDDDD? signed 16 integers and replacement char
    return _charescape.sub(_replace, escaped).encode('ascii')


class Codec(codecs.Codec):
    def encode(self, input, errors='strict'):
        return rtfunicode_encode(input, errors), len(input)


class IncrementalEncoder(codecs.IncrementalEncoder):
    def encode(self, input, final=False):
        return rtfunicode_encode(input, self.errors)


class StreamWriter(Codec, codecs.StreamWriter):
    pass


def rtfunicode(name):
    if name == 'rtfunicode':
        return codecs.CodecInfo(
            name='rtfunicode',
            encode=Codec().encode,
            decode=Codec().decode,
            incrementalencoder=IncrementalEncoder,
            streamwriter=StreamWriter,
        )

codecs.register(rtfunicode)

然后,您可以编码为“rtfunicode”,而不是编码为“iso-8859-15”:

>>> u'\u20AC'.encode('rtfunicode') # EURO currency symbol
'\\u8364?'

以这种方式对您插入 RTF 文档的任何文本进行编码。

注意它只支持 UCS-2 unicode ( \uxxxx, 2 bytes),不支持 UCS-4 ( \Uxxxxxxxx, 4 bytes);rtfunicode1.1 通过简单地将 UTF-16 代理对编码为两个有\uDDDDD?符号整数来支持这些。

于 2012-06-01T15:13:18.293 回答
0

好消息是你没有做错任何事。坏消息是 RTF 无论如何都被解读为 ISO 8859-1。

>>> print u'€'.encode('iso-8859-15').decode('iso-8859-1')
¤

如果您希望正确读取它,则需要使用Unicode 转义。

>>> print hex(ord(u'€'))
0x20ac
于 2012-06-01T15:12:46.820 回答