ios - Swift countElements() 在计数标志 emoji 时返回不正确的值

标签 ios swift unicode emoji countelements

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 获取字符数。


(Swift 3 及更早版本的旧答案:)

来自 "3 Grapheme Cluster Boundaries" 在“标准附件 #29 UNICODE 文本分割”中: (强调):

A legacy grapheme cluster is defined as a base (such as A or カ) followed by zero or more continuing characters. One way to think of this is as a sequence of characters that form a “stack”.

The base can be single characters, or be any sequence of Hangul Jamo characters that form a Hangul Syllable, as defined by D133 in The Unicode Standard, or be any sequence of Regional_Indicator (RI) characters. The RI characters are used in pairs to denote Emoji national flag symbols corresponding to ISO country codes. Sequences of more than two RI characters should be separated by other characters, such as U+200B ZWSP.

(感谢@rintaro 提供的链接)。

一个 Swift Character 代表一个扩展的字素簇,所以它是(根据 到此引用)更正任何区域指示符号序列 被算作一个字符。

您可以用零宽度非连接器分隔“标志”:

let str1 = "🇩🇪\u{200C}🇩🇪"
print(str1.characters.count) // 2

或插入零宽度空间:

let str2 = "🇩🇪\u{200B}🇩🇪"
print(str2.characters.count) // 3

这也解决了可能的歧义,例如应该是“🇫 🇷 🇺 🇸” 是“🇫 🇷🇺 🇸”还是“🇫🇷 🇺🇸”?

另见 How to know if two emojis will be displayed as one emoji?关于一个可能的方法 计算 Swift 字符串中“组合字符”的数量, 这将为您的 let str1 = "🇩🇪🇩🇪🇩🇪🇩🇪🇩🇪" 返回 5

关于ios - Swift countElements() 在计数标志 emoji 时返回不正确的值,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/26862282/

相关文章:

ios - 如何在 SwiftUI 中点击 ActionSheet.Button 后呈现 View ?

ios - 通过字节数组将图像从 iOS 发送到 .net 服务器

ios - 带分段控制的从左到右的 Tableview 动画

ios - 解析 findObjectsInBackgroundWithBlock 错误部分不起作用

python - 通过 scrapy 抓取数据的 unicode 问题

javascript - 如何对包含 unicode 字符的 url 进行转义

ios - UICollectionView 离屏截图

swift - 在 Swift 中使用文本字段设置 MKAnnotation 的标题

swift - 类型 'AnyObject' 的值没有成员 ''

python - 在 python 中读取一个 unicode 文件,它以与 python 源代码相同的方式声明其编码