she*_*lll 0 string utf-8 go swift
我在Go和Swift中有应用程序处理字符串,例如查找子字符串及其索引.起初它甚至可以使用多字节字符(例如表情符号),使用Go utf8.RuneCountInString()和Swift的原生字符串.
但是有一些UTF8字符可以打破字符串长度和子字符串的索引,例如字符串"Lorem ?? ipsum":
Go的utf8.RuneCountInString("Lorem ?? ipsum")返回17,起始索引ipsum为12.
Swift的"Lorem ?? ipsum".count返回16,起始索引ipsum为11.
使用Swift String utf8,utf16或者使用cast来NSString提供不同的长度和索引.还有其他表情符号由多个其他表情符号组成,它们提供更有趣的数字.
这是Go 1.8和Swift 4.1.
有没有办法用Go和Swift获得相同的字符串长度和子字符串索引?
编辑
我基于@ MartinR的答案创建了一个Swift String扩展:
extension String {
func runesRangeToNSRange(from: Int, to: Int) -> NSRange {
let length = to - from
let start = unicodeScalars.index(unicodeScalars.startIndex, offsetBy: from)
let end = unicodeScalars.index(start, offsetBy: length)
let range = start..<end
return NSRange(range, in: self)
}
}
Run Code Online (Sandbox Code Playgroud)
在Swift中,a Character是一个"扩展的字形集群",每个"","","✌️","",""都算作单个字符.
我没有使用Go的经验,但正如我从Go中了解字符串,符号,符文和字符一样,"符文"是一个Unicode代码点,它基本上对应UnicodeScalar于Swift中的一个.
在您的示例中,差异来自"✌️",它被视为单个Swift字符,但是由两个Unicode标量构建:
print("??".count) // 1
print("??".unicodeScalars.count) // 2
Run Code Online (Sandbox Code Playgroud)
下面是一个如何根据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
}
Run Code Online (Sandbox Code Playgroud)
如您所见,这与Go中的示例中的数字相同.
| 归档时间: |
|
| 查看次数: |
214 次 |
| 最近记录: |