如何在RTF中正确解码十六进制值

时间:2019-02-14 20:07:44

标签: python character-encoding nlp rtf

不幸的是,这只掉了两个兔子洞,文本编码和RTF。但是就在这里。

背景

我正在NLP文本管道上工作,我们需要将RTF转换为纯文本,换句话说,我们需要删除RTF控制字符并保持文本内容不变。我们正在用python构建管道,它有几个要求,这些要求使我们无法在生产中使用Apache Tikka之类的东西。

我知道,如果文档的作者键入了非ASCII字符,则RTF可以包含十六进制值,例如\'a9。我也知道文档中的控制字符的第一个序列指定了如何解码这些十六进制值,例如\ansicpg1252。例如,在这种情况下,文档开始处\ansicpg1252的存在意味着\'a9应该按照the windows-1252 encoding解释为Unicode代码点00A9 (COPYRIGHT SIGN)

问题

我遇到了第一组控制字符中带有\ansicpg1252的RTF文档,但是在文档中的某些地方出现了以下十六进制文字\'81\'aa。这是令人困惑的,因为0x81的编码中未定义windows-1252。我以为可能是utf-8,但是在utf-8中也没有定义。

WordPad.exe用以下字符表示这两个字节:↑

Apache Tikka使用相同的字符↑

此字符对应于Unicode代码点2191 (Upwards Arrow),事实证明,我们的神秘字节0x81AA是使用Windows Code Page 932 encoding对该字符进行编码的结果,该字符包含日语字符

作为参考,RTF文档中这两个字节的完整上下文为

\plain\f1\fs20 \'81\'aa\plain\f0\fs20

,文档在\fonttbl组中包含以下条目:

{\f1\fmodern\fcharset128\fprq1 MS Mincho;}

据我所知,这意味着\f1之后的任何文本都应使用MS Mincho字体呈现,这是有道理的,因为MS Mincho包含日语字形。但是,RTF解析器如何知道应该使用0x81AA而不是文件第一行中指定的Windows Code Page 932来解码ansicpg1252?我是否需要知道某些字体暗含某些编码?

我最好的猜测是,它与\fonttbl条目中\fcharset128的部分有关,但我不确定。

1 个答案:

答案 0 :(得分:1)

发表评论后,我做了更多的挖掘工作……

fcharset参数来自一组固定值,这些值映射到所使用的编码。这是一个示例:

https://github.com/joniles/rtfparserkit/blob/master/src/main/java/com/rtfparserkit/parser/standard/FontCharset.java

我从内存中认为我从Microsoft的RTF规范文档(https://www.microsoft.com/en-us/download/details.aspx?id=10725)中挑选了这些