计算Unicode字符串长度而不组合标记

Phr*_*ogz 4 ruby unicode

考虑以下分析三字节UTF-8字符串的Ruby代码:

#encoding: utf-8
s = "\x65\xCC\x81"
p [s.bytesize, s.length, s, s.encoding.name]
#=> [3, 2, "é", "UTF-8"]
Run Code Online (Sandbox Code Playgroud)

正如本页面上所描述的那样,上面确实一个两个字符的字符串:拉丁文小写字母,e然后是" 结合急性重音".但是,它看起来像一个字符,这在布置固定宽度显示时很重要.

例如,查看此目录列表中 "moiré.svg"的两个条目,并注意其中一个条目如何搞乱列对齐.

如何计算Ruby中字符串的"等宽视觉长度",其中不包含任何零宽度组合字符?(一个有效的技术可能变换一个Unicode字符串到它的规范表示的方式,到上述转动"\xC3\xA9"它也像é,但有一个length1.)

joe*_*son 5

unicode_utils gem可能会有所帮助:

http://unicode-utils.rubyforge.org/UnicodeUtils.html

有一种char_display_width方法:

require "unicode_utils/char_display_width"
UnicodeUtils.char_display_width("?")  # => 2
UnicodeUtils.char_display_width(0x308) # => 0
UnicodeUtils.char_display_width("a")   # => 1
Run Code Online (Sandbox Code Playgroud)

有一个字符串display_width方法:

require "unicode_utils/display_width"
UnicodeUtils.display_width("??") => 4
UnicodeUtils.display_width("12") => 2
UnicodeUtils.display_width("a\u{308}") => 1
Run Code Online (Sandbox Code Playgroud)

另外看看each_grapheme.

(感谢Michael Anderson指出了其他方法)