let str1 = “🇩🇪🇩🇪🇩🇪🇩🇪🇩🇪” let str2 = “🇩🇪.🇩🇪.🇩🇪.🇩🇪.🇩🇪.”
println("\(countElements(str1)), \(countElements(str2))")
结果:1、10
但是str1不应该有5个元素吗?
该错误似乎仅在使用标志表情符号时发生。
Swift 4(Xcode 9)更新
从Swift 4开始(通过Xcode 9 beta测试),根据Unicode 9标准的规定,每隔一个区域指示器符号,字素簇就会断开:
let str1 = "🇩🇪🇩🇪🇩🇪🇩🇪🇩🇪" print(str1.count) // 5 print(Array(str1)) // ["🇩🇪", "🇩🇪", "🇩🇪", "🇩🇪", "🇩🇪"]
同样String也是其字符的集合,因此可以使用来获得字符数str1.count。
String
str1.count
(Swift 3及更高版本的旧答案:)
从“3个字形群集边界” 的“标准附件#29 Unicode文本分割”(强调):
传统字素簇定义为基数(例如A或カ),后跟零个或多个连续字符。一种考虑方式是将字符序列形成一个“堆栈”。 基数可以是单个字符,也可以是形成hangul音节的任何Hangul Jamo字符序列(如Unicode标准中的D133所定义),也可以 是Regional_Indicator(RI)字符的任何序列 。RI字符成对使用,以表示与ISO国家代码相对应的Emoji表情符号。超过两个RI字符的序列 应由其他字符分隔 ,例如U + 200B ZWSP。
传统字素簇定义为基数(例如A或カ),后跟零个或多个连续字符。一种考虑方式是将字符序列形成一个“堆栈”。
基数可以是单个字符,也可以是形成hangul音节的任何Hangul Jamo字符序列(如Unicode标准中的D133所定义),也可以 是Regional_Indicator(RI)字符的任何序列 。RI字符成对使用,以表示与ISO国家代码相对应的Emoji表情符号。超过两个RI字符的序列 应由其他字符分隔 ,例如U + 200B ZWSP。
(感谢@rintaro提供链接)。
Swift字符表示扩展的字素簇,因此(根据此参考资料)将区域指示符符号的任何序列都计为单个字符是正确的。
您可以用零宽度非JOINER分隔“标志”:
let str1 = "🇩🇪\u{200C}🇩🇪" print(str1.characters.count) // 2
或插入零宽度空间:
let str2 = "🇩🇪\u{200B}🇩🇪" print(str2.characters.count) // 3
这也解决了可能的歧义,例如,“🇫”是“🇫”还是“🇫🇷”?
另请参见如何知道两个表情符号是否将显示为一个表情符号?关于一种可能的方法,该方法可以计算Swift字符串中“组成字符”的数量,该方法将返回5给您let str1 = "🇩🇪🇩🇪🇩🇪🇩🇪🇩🇪"。
5
let str1 = "🇩🇪🇩🇪🇩🇪🇩🇪🇩🇪"