红宝石有毒表情符号?

问题描述 投票:0回答:1

我在 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..

知道为什么表情符号☺️会产生这个结果吗?

ruby bash macos unicode
1个回答
0
投票

因为☺️是由两个字符组成的:

  1. U+263A(白色笑脸)
  2. ◌️
    U+FE0F(变化选择器-16)
"☺️".codepoints.map { |c| c.to_s(16) }
#=> ["263a", "fe0f"]

您可以通过

each_grapheme_cluster
得到预期的结果:

"0😀2☺️4🤪6🥳8🥸".each_grapheme_cluster.to_a
#=> ["0", "😀", "2", "☺️", "4", "🤪", "6", "🥳", "8", "🥸"]
© www.soinside.com 2019 - 2024. All rights reserved.