【问题标题】:Reliable function to get position of substring in string in Swift在 Swift 中获取字符串中子字符串位置的可靠函数
【发布时间】:2016-12-22 11:28:12
【问题描述】:

这对英语很有效:

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 正常工作。

【问题讨论】:

    标签: swift string encoding


    【解决方案1】:

    Swift StringCharacters 的集合,每个 Character 表示“扩展的 Unicode 字素簇”。

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

    例子:

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

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

    您的函数从一开始就计算Characters 的数量 从大海捞针到针头,那是不同的 来自 UTF-16 代码点的数量。

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

    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
    }
    

    或者,使用 Swift 字符串的 utf16 视图 计算 UTF-16 代码单元:

    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
    }
    

    (参见示例 NSRange to Range<String.Index> 了解更多在 Range&lt;String.Index&gt; 之间转换的方法 和NSRange)。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2021-04-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多