2016-03-06 85 views
4

一般斯威夫特是真的智能计数字形集群作为一个单一的字符。如果我想打一个黎巴嫩国旗,例如,我可以将两者结合起来的Unicode字符为什么斯威夫特将这个字形集群统计为两个字符而不是一个字符?

  • U + 1F1F1区域指标符号字母L
  • U + 1F1E7区域指标符号字母B

并预期这是斯威夫特一个字符:

let s = "\u{1f1f1}\u{1f1e7}" 
assert(s.characters.count == 1) 
assert(s.utf16.count == 4) 
assert(s.utf8.count == 8) 

但是,让我们说我要让菲茨帕特里克的Type-5的骑自行车的表情符号。如果我结合

  • U + 1F6B4骑车
  • U + 1F3FE EMOJI MODIFIER FITZPATRICK TYPE-5

斯威夫特计数,这种组合人物!

let s = "\u{1f6b4}\u{1f3fe}" 
assert(s.characters.count == 2) // <----- WHY? 
assert(s.utf16.count == 4) 
assert(s.utf8.count == 8) 

为什么这两个字符而不是一个?

表明为什么我希望它是1,注意,这个集群实际上是解释为一个有效的表情符号:答案

enter image description here

+0

这看起来像一个错误报告。为什么不把它发送给Swift团队? –

+0

http://unicode.org/reports/tr51/有点含糊:“只要这些字符中的一个紧跟某些字符(例如WOMAN),那么字体应该将该序列显示为单个字形...” –

+2

在https://bugs.swift.org/browse/SR-375有关于这一点的讨论。不幸的是,这并不能说明情况。 – emrys57

回答

7

部分在emrys57的评论中提到的bug report中给出。将一个Unicode字符串拆分为“字符”时,Swift显然使用UAX #29 Unicode Text Segmentation中定义的字形集群边界。有一个rule not to break between regional indicator symbols,但表情符号修饰符没有这样的规则。因此,根据UAX#29,字符串"\u{1f6b4}\u{1f3fe}"包含两个字素集群。看到肯惠斯勒this message Unicode的邮件列表上的解释:

这源于一个事实,即该修饰的后备行为 仅仅作为独立的象形blorts,即颜色样本图像。 [...]您需要额外的,具体的 关于这些序列的知识 - 它不只是从 默认落实到字形集群的UAX#29规则。