let str1 = ""
let str2 = "....."
println("\(countElements(str1)), \(countElements(str2))")
结果:1,10
但是str1难道不应该有5个元素吗?
当我使用旗帜表情时,似乎只发生了这个bug。
let str1 = ""
let str2 = "....."
println("\(countElements(str1)), \(countElements(str2))")
结果:1,10
但是str1难道不应该有5个元素吗?
当我使用旗帜表情时,似乎只发生了这个bug。
Swift 4更新(Xcode 9)
从Swift 4开始(经过Xcode 9测试),基于Unicode 9标准,每两个区域指示符号后面将会中断字形簇。
let str1 = ""
print(str1.count) // 5
print(Array(str1)) // ["", "", "", "", ""]
同样,String
是由其字符组成的集合,因此可以使用str1.count
获得字符计数。
(旧版Swift 3及更早版本的答案:)
从“3 Grapheme Cluster Boundaries”中 在“标准Annex #29 UNICODE TEXT SEGMENTATION”中: (强调添加):
传统的字形群集被定义为一个基础(例如A或カ) 零个或多个连续字符。可以将其视为形成“堆栈”的字符序列。
基数可以是单个字符,也可以是由Hangul Jamo字符序列组成的任何序列 根据Unicode标准中的D133定义,成为Hangul音节,或是由任何区域指示符(RI)字符序列。 RI字符成对使用以表示对应于ISO国家代码的表情符号国旗符号。超过两个RI字符的序列应分隔其他字符, 例如U+200B ZWSP。
(感谢@ rintaro提供的链接)。
Swift Character表示扩展的字形簇,因此(根据此参考资料)正确的是将任何区域指示符号 序列计为一个字符。
您可以使用零宽度非连接符分隔“标志”:
let str1 = "\u{200C}"
print(str1.characters.count) // 2
或者插入一个零宽空格:
let str2 = "\u{200B}"
print(str2.characters.count) // 3
这也解决了可能存在的歧义,例如“”应该是“”还是“”?
另请参见如何确定两个表情符号是否将显示为一个表情符号? 关于一种可能的方法来计算Swift字符串中“组合字符”的数量,对于您的let str1 = ""
将返回5
。
以下是我为解决这个问题而采用的方法,适用于 Swift 3:
let str = "" //or whatever the string of emojis is
let range = str.startIndex..<str.endIndex
var length = 0
str.enumerateSubstrings(in: range, options: NSString.EnumerationOptions.byComposedCharacterSequences) { (substring, substringRange, enclosingRange, stop) -> () in
length = length + 1
}
print("Character Count: \(length)")
let str1 = "\u{1F1E6}\u{1F1E7}\u{1F1E8}\u{1F1E9}\u{1F1EA}\u{1F1EB}"
打印出来是 `` 但被计算为单个字符。 - Martin Rstr1.startIndex.successor() == str1.endIndex
。 - rintaro