如何输入非bmp unicode(超过4个字符的十六进制)作为输入到Mathematica



问题描述:数学软件使用":nnnn"作为unicode输入的语法。例如,如果我们进入":6c34",我们得到"水"(中文"水")。但是如果想进入":1f618"(抛脸一吻)呢?当我尝试这个时,我得到了"ὡ8",而不是"a face throwing a kiss"。因此,在输入"8"之前,Mathematica计算了":1f61"

问题:如何延迟这个求值,或者如何输入unicode输入(对于超过4个字符的十六进制)?

软硬件平台:我在英特尔的Mac电脑上运行Mathematica 8。我尝试了命令行版本的Mathematica和Mathematica笔记本,它们的行为是一样的。

谢谢。


反射:Unicode是一个可扩展的标准,它可以增长(它确实增长:))。为了有效和有用(8位、16位或32位编码),实现本标准的软件系统可能只实现本标准的一个子集。作为某个软件包的用户,不应该假设一旦软件说它支持unicode,它就支持通用的unicode集。

简短的回答:你不能这样做,因为Mathematica不支持这些字符。请参阅文章末尾的一些解决方法。

只是澄清一些事情:

对于32位编码来说,不需要来处理超过~65000个Unicode字符。Unicode最常用的编码,UTF-8和UTF-16,是多字节编码,这意味着使用可变数量的字节来表示字符。UTF-16可以使用2或4个字节来表示一个字符。Mathematica内核将把每个2字节序列解释为字符串中的单个字符,有时会导致一些无效字符(当遇到4字节序列时)。这可能被认为是一个bug。前端处理4字节序列的方式非常情绪化,这绝对是一个bug。

有限方法

当严格地在内核中工作时(例如从文件中读取Unicode数据),我有时使用这个函数作为解决方法来获得2单元(4字节)UTF-16序列的实际Unicode代码点:

toCodePoint[{a_, b_}] /; 16^^d800 <= a <= 16^^dbff && 16^^dc00 <= b <= 16^^dfff := (a - 16^^d800)*2^10 + (b - 16^^dc00) + 16^4

可以使用

Split[ToCharacterCode[str], If[16^^d800 <= # <= 16^^dbff, True] &]

将UTF-16字符串正确拆分为Unicode字符(长度为1或长度为2,取决于字符)。

这是一个丑陋和不方便的解决方案,它将不允许你在前端显示这些字符中的任何字符,除非你想出一些hack,例如从unicode.org导入字形参考图像(至少对于CJK他们有)。

参见

参见我之前关于同一主题的问题:在Mathematica中读取UTF-8编码的文本文件

如果你要和中国人一起工作,你可能会遇到另一个问题:让Mathematica前端服从FontFamily选项

根据本页Mathematica 8帮助:

Mathematica supports both 8- and 16-bit raw character encodings.

他们大概是在说他们不支持32位编码,而这是支持你想要的字符所必需的。

作为进一步的证据(在文档中没有明确说明的情况下),同一页面上支持的编码列表中没有32位编码。32位编码显然只支持MathLink。我想是用户需求不够。

最新更新