不幸的是,这个有两个兔子洞,文本编码和RTF。但在这里。
我正在开发一个NLP文本管道,我们需要将RTF转换为纯文本,换句话说,我们需要删除RTF控制字符并保持文本内容不变。我们正在python中构建管道,它有几个要求阻止我们在生产中使用像Apache Tikka这样的东西。
我知道如果文档的作者输入了非ascii字符,RTF可以包含十六进制值,例如\'a9
。我还知道文档中的第一个控制字符序列指定了如何解码这些十六进制值,例如\ansicpg1252
。例如,在这种情况下,在文档开头存在\ansicpg1252
意味着\'a9
应根据00A9 (COPYRIGHT SIGN)
解释为unicode代码点the windows-1252 encoding。
我在第一组控制字符中遇到了带有\ansicpg1252
的RTF文档,但是文档中有几个地方出现以下十六进制文字,\'81\'aa
。这是令人困惑的,因为0x81
在windows-1252
编码中是未定义的。我想也许它可能是utf-8
,但它也没有在utf-8
中定义。
WordPad.exe用这个字符表示这两个字节:↑
Apache Tika使用相同的字符,↑
这个字符对应于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
部分有关,但我不确定。
发表评论后,我做了一些挖掘......
fcharset
参数来自一组固定的值,这些值映射到所使用的编码。这是一个例子:
从内存中我想我从微软的RTF规范文档中选择了这些文件(https://www.microsoft.com/en-us/download/details.aspx?id=10725)