程序matically判断Unicode字符在终端中占用是否超过一个字符空间
我发现,在Mac OS X的终端中,有些Unicode字符占用的空间超过一个字符的宽度。比如说27FC(一个长的右箭头)。它打印出来的宽度是两个字符,但第二个字符会覆盖在下一个字符上,所以你必须输入⟼<space>
才能正确显示。例如,⟼a
打印出来的效果是这样的:
(我把字体调大了,这样你能看得更清楚,但其实所有字体大小都是这样)。
顺便说一下,这里用的是Mac OS X 10.6终端应用中的Menlo字体。
另外,23B3(求和符号)实际上在Safari中打印出来的宽度和高度都是两个字符(在浏览器中也是这样,注意它和上面一行是重叠的)⎲
不过,在Ubuntu的终端中,这些字符的宽度和高度都不会超过一个字符。
有没有办法通过编程来判断一个字符是否占用超过一个字符的空间呢?
我在用Python,所以如果能用纯Python或者在POSIX环境下(也就是我可以用os
模块调用一些bash命令)的方法就更好了。
另外,我还想提一下,如果我把终端字体设置中的“字符间距”从默认的1.0调到1.5,那么效果就会变成这样:
最后,如果能对这些现象提供一些解释(比如为什么会这样)那就更好了。
3 个回答
这是OS X终端中的一个错误。
我不建议你尝试绕过这个问题,因为这样做在其他系统上(比如Linux)可能会出问题,而且这个问题可能最终会在Mac上被修复。此外,这样做还会让那些把内容粘贴到其他应用程序的人感到困惑。
不行,因为我们无法知道终端使用的是什么字体。记住,永远要使用等宽字体,这是一课。
之所以会这样,是因为终端使用的是一种“单元格”字体布局方式(也就是说,字符是按照特定的X和Y坐标打印的,不管它们的实际大小),而浏览器则使用的是“流式”字体布局方式(后面的字符会在前一个字符结束的地方打印)。
虽然你给出的具体例子和这个没什么关系(在我的Ubuntu上,所有这些字符都只显示为一个字符的大小),但是CJK字符(中文、日文、韩文字符)有一个unicode属性,表示它们比普通字符宽,在某些终端中会显示为双倍宽度。
比如,在Python中:
# 'a' is a normal (narrow) character
# '愛' can be interpreted as a double-width (wide) character
import unicodedata
assert unicodedata.east_asian_width('a') == 'N'
assert unicodedata.east_asian_width('愛') == 'W'
除此之外,我觉得没有规定某些字符应该占多大空间,除了你使用的字体中字符的实际大小(而你的终端可能忽略了这一点,正如Ignacio所说的)。
想了解更多关于“东亚宽度”属性的信息,可以查看 http://www.unicode.org/reports/tr11/