我在 MacOS 14.6.1 上安装了 Ruby 3.3.4。
假设我在 shell 中有这个字符串:
$ st="0😀2☺️4🤪6🥳8🥸"
$ echo "$st"
0😀2☺️4🤪6🥳8🥸
如果我现在将该字符串输入 Ruby,我会得到分解为多个组成部分的第二个表情符号:
$ echo "$st" | ruby -lne 'p $_.split("")'
["0", "😀", "2", "☺", "️", "4", "🤪", "6", "🥳", "8", "🥸"]
^ ^ # should be ONE grapheme
如果我从文件中读取该字符串也是一样:
$ cat wee_file
0😀2☺️4🤪6🥳8🥸
$ ruby -lne 'p $_.split("")' wee_file
["0", "😀", "2", "☺", "️", "4", "🤪", "6", "🥳", "8", "🥸"]
IRB 中也是一样:
irb(main):001> File.open('/tmp/wee_file').gets.split("")
=> ["0", "😀", "2", "☺", "️", "4", "🤪", "6", "🥳", "8", "🥸", "\n"]
但是,如果我用另一个表情符号(也是多字节的)替换☺️,问题就消失了:
$ st2="0😀2🐱4🤪6🥳8🥸"
$ echo "$st2" | ruby -lne 'p $_.split("")'
["0", "😀", "2", "🐱", "4", "🤪", "6", "🥳", "8", "🥸"]
# also from a file and also in IRB..
知道为什么表情符号☺️会产生这种结果吗?
这是因为☺️由两个字符组成:
☺
U+263A(白色笑脸)◌️
U+FE0F(变体选择器-16)后者用于请求前一个字符的表情符号呈现。
您可以通过以下方式获取预期结果
grapheme_clusters
或通过以下方式枚举它们each_grapheme_cluster
: