我在Go和Swift中有应用程序处理字符串,例如查找子字符串及其索引。起初它甚至可以很好地使用多字节字符(例如表情符号),使用Go的utf8.RuneCountInString()
和Swift的原生字符串。
但是有一些UTF8字符会破坏字符串长度和子字符串的索引,例如字符串"Lorem ✌️ ipsum"
:
Go {'1}}返回17,utf8.RuneCountInString("Lorem ✌️ ipsum")
的起始索引为12。
Swift的ipsum
返回16,"Lorem ✌️ ipsum".count
的起始索引为11。
使用Swift String' ipsum
,utf8
或转换为utf16
也会提供不同的长度和索引。还有其他表情符号由多个其他表情符号组成,可以提供更有趣的数字。
这是Go 1.8和Swift 4.1。
有没有办法获得相同的字符串长度和子字符串'与Go和Swift具有相同值的索引?
修改
我根据@ MartinR的优秀答案创建了一个Swift String扩展:
NSString
答案 0 :(得分:7)
在Swift中,Character
是一个“扩展的字形集群”,每个“”,“”,“✌️”,“”,“”都算作单个字符。
我没有Go的经验,但据我所知Strings, bytes, runes and characters in Go,
“符文”是一个Unicode代码点,它基本上对应于Swift中的UnicodeScalar
。
在你的例子中,区别来自“✌️” 算作单个Swift字符,但是由两个Unicode标量构建:
print("✌️".count) // 1
print("✌️".unicodeScalars.count) // 2
以下是如何计算长度和偏移量的示例 Unicode标量术语:
let s = "Lorem ✌️ ipsum"
print(s.unicodeScalars.count) // 17
if let idx = s.range(of: "ipsum") {
print(s.unicodeScalars.distance(from: s.startIndex, to: idx.lowerBound)) // 12
}
如您所见,这与Go中的示例中的数字相同。
答案 1 :(得分:0)
A rune
in Go identifies a specific UTF-8 code point;这并不一定意味着它将1:1映射到视觉上不同的字符。某些字符可能由多个符文/代码点组成,因此计数符文可能无法提供您对字符串的视觉检查所期望的内容。我不知道Swift中"some text".count
实际上有多重要,所以我不能在那里提供任何比较。