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

Nin*_*ing 9 unicode wolfram-mathematica supplementary astral-plane

问题描述: Mathematica "\:nnnn" 用作unicode输入的语法.例如,如果我们进入 "\:6c34",我们得到"?"(中文"水").但如果有人想进入"\:1f618"(面对投掷一个吻)会怎样.当我尝试这个时,我得到了"?8",而不是"a face throwing a kiss".所以,Mathematica "\:1f61"在我进入之前进行了评估"8".

问题: 我们如何延迟此评估或如何输入任何unicode输入(对于超过4个字符的十六进制)?

软件和硬件平台: 我在Intel Mac上运行Mathematica 8.我尝试了Mathematica和Mathematica笔记本的命令行版本,它们的行为相同.

谢谢.


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

Sza*_*lcs 9

简短回答:你不能这样做,因为Mathematica不能正确支持这些字符.有关变通方法,请参阅帖子的最后部分.

只是为了清理一些事情:

没有必要为32位编码,可处理超过65000〜Unicode字符.用于Unicode,UTF-8和UTF-16的最常见编码是多字节编码,这意味着使用可变数量的字节来表示字符.UTF-16可以使用2或4个字节来表示字符.Mathematica内核将每个2字节序列解释为字符串中的单个字符,偶尔会导致一些无效字符(遇到4字节序列时).这可能被视为一个错误.关于它如何处理4字节序列的前端非常喜怒无常,这绝对是一个错误.

有限的解决方法

当严格在内核中工作时(例如从文件中读取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
Run Code Online (Sandbox Code Playgroud)

您可以使用

Split[ToCharacterCode[str], If[16^^d800 <= # <= 16^^dbff, True] &]
Run Code Online (Sandbox Code Playgroud)

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

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

也可以看看

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

如果您打算使用中文,您可能会遇到另一个问题: 让Mathematica前端服从FontFamily选项


Cod*_*key 5

根据Mathematica 8帮助中的这个页面:

Mathematica supports both 8- and 16-bit raw character encodings.
Run Code Online (Sandbox Code Playgroud)

据推测,他们说他们不支持32位编码,因为需要支持你想要的角色.

作为进一步的证据(在文档中没有明确的声明),同一页面上支持的编码列表没有32位编码.显然,MathLink仅支持32位编码.我想用户需求不足.

  • 澄清一些困惑:没有必要"支持32位编码"来正确支持Unicode.UTF-16是一种16位编码,但它可以通过使用单字(2字节)和双字(4字节)单元对所有Unicode字符进行编码,超过65000个.Mathematica无法正确处理双字单元.从我之前相关问题的评论中我得到的印象是这是一个*bug*,因为有时这些在Windows 7中正确显示,但在保存并打开笔记本后,它们会被破坏.http://stackoverflow.com/q/5597013/211232 (2认同)