在rtf标记中检测多字节和汉字

Sep*_*eph 2 language-agnostic unicode rtf localization multibyte

我正在尝试翻译解析RTF格式的消息(我需要保留格式化标签,所以我不能使用你只是粘贴到一个RichTextBox并获取.PlainText出来的技巧)

a?b??c??d直接粘贴到Wordpad中的字符串的RTF代码:

{\rtf1\ansi\ansicpg1252\deff0\deflang2057{\fonttbl{\f0\fnil\fcharset0 Calibri;}{\f1\fswiss\fcharset128 MS PGothic;}{\f2\fnil\fcharset1 Shonar Bangla;}{\f3\fswiss\fcharset161{\*\fname Arial;}Arial Greek;}}
{\*\generator Msftedit 5.41.21.2510;}\viewkind4\uc1\pard\sa200\sl276\slmult1\lang9\f0\fs22 a\f1\fs24\'8a\'ee\f0\fs22 b\f2\fs24\u2478?\u2498?\f0\fs22 c\f3\fs24\'cf\'e9\f0\fs22 d\par
}
Run Code Online (Sandbox Code Playgroud)

如果你与RTF没什么关系,很难弄明白.所以这就是我正在看的

\'8a\'ee\f0\fs22 b\f2\fs24\u2478?\u2498?\f0\fs22 c\f3\fs24\'cf\'e9
Run Code Online (Sandbox Code Playgroud)

注意?(u+57FA)是\'8a\'ee??,这实际上是两个字符?(\u2478?)和?(\u2498?),是\u2478?\u2498?其是很好,但??它是两个单独的字符??\'cf\'e9.

有没有办法确定我是否正在查看应该是一个字符的内容,例如?= \'bb\'f9或两个字符??= \'cf\'e9

我当时想的可能\lang是它,但事实并非如此,因为\lang它不会从第一次设置时改变.我已经从Charset字体中的不同值中考虑了不同的代码页,但它似乎没有告诉我是否应该将两个Unicode引用彼此相邻处理为双字节字符.

如何判断我正在查看的字符应该是双字节(或多字节)还是单字节?

bob*_*nce 7

\'xxescape表示字节,应使用fcharset编码进行解释.(或者可能cchs.ansicpg如果不存在则回落.)

您需要知道编码密切地能够决定单个\'xx序列是单独表示一个字符还是仅仅是多字节字符的一部分; 通常,在使用您可用的任何库或OS接口将该字节字符串转换为Unicode字符串之前,您将使用每个文本部分作为一个单元,以避免必须为RTF支持的每个代码页编写逐字节解析器.

\uxxxx?转义表示UTF-16代码单元.这要简单得多,但是Word [pad]仅作为最后的手段产生这种形式的编码,因为它与早期的RTF版本不兼容.(?是接收器无法处理Unicode时的后备字符.)

所以:

  • 这两个字符??表示为两个字节转义,因为与该文本段相关联的字体使用希腊单字节编码(字符集161 = cp1253).

  • 一个字符?表示为两个字节转义,因为与该文本段相关联的字体使用日语多字节编码(字符集128 =cp932≈Shift-JIS).在Shift-JIS中,前导\'8a字节表示另一个字节,最高位设置范围内的各种其他字节(但不是全部).

  • 这两个字符??表示为Unicode代码单元转义,因为没有其他选项:没有任何包含孟加拉语字符的RTF兼容代码页.(ISCII的代码页57003来得晚了.)

  • 是的,有一系列的前导字节表示多字节序列,并且该范围对于每个多字节编码都不同.请参阅[此处的fcharsetN列表](http://latex2rtf.sourceforge.net/rtfspec_6.html),然后查找各个代码页.例如[cp932](http://msdn.microsoft.com/en-gb/goglobal/cc305152)(≈Shift-JIS).通过一次读取一段文本中的所有字节,然后使用环境中可用的任何现有编码处理(例如,.NET中的编码)转换为字符,而不是尝试读取一个字节,这样做会更简单逐字节. (3认同)