可靠的函数来获取Swift中字符串中子字符串的位置

时间:2016-12-22 11:28:12

标签: swift string encoding

这对英语很有用:

public static func posOf(needle: String, haystack: String) -> Int {
    return haystack.distance(from: haystack.startIndex, to: (haystack.range(of: needle)?.lowerBound)!)
}

但是对于外来字符,返回的值总是太小。例如"का"被认为是一个单位而不是2.

posOf(needle: "काम", haystack: "वह बीना की खुली कोयला खदान में काम करता था।") // 21

我稍后使用NSRange(location:length:)中的21,其中需要28才能使NSRange正常工作。

1 个答案:

答案 0 :(得分:5)

Swift StringCharacter s的集合,每个Character 代表“扩展的Unicode字形集群”。

NSString是UTF-16代码单元的集合。

示例:

print("का".characters.count) // 1
print(("का" as NSString).length) // 2

Swift String范围表示为Range<String.Index>NSString范围表示为NSRange

您的函数从头开始计算Character的数量 干草堆到针的开头,这是不同的 从UTF-16代码点的数量。

如果您需要“兼容NSRange” 字符数,那么最简单的方法就是使用 range(of:)的{​​{1}}方法:

NSString

或者,使用Swift字符串的let haystack = "वह बीना की खुली कोयला खदान में काम करता था।" let needle = "काम" if let range = haystack.range(of: needle) { let pos = haystack.distance(from: haystack.startIndex, to: range.lowerBound) print(pos) // 21 } let nsRange = (haystack as NSString).range(of: needle) if nsRange.location != NSNotFound { print(nsRange.location) // 31 } 视图 计算UTF-16代码单位:

utf16

(参见例如 NSRange to Range<String.Index>了解更多在if let range = haystack.range(of: needle) { let lower16 = range.lowerBound.samePosition(in: haystack.utf16) let pos = haystack.utf16.distance(from: haystack.utf16.startIndex, to: lower16) print(pos) // 31 } 之间进行转换的方法 和Range<String.Index>)。