如何在 NSRange 中转换范围? [复制]

Posted

技术标签:

【中文标题】如何在 NSRange 中转换范围? [复制]【英文标题】:How to convert Range in NSRange? [duplicate] 【发布时间】:2017-04-05 13:45:59 【问题描述】:

我正在 swift 3 中更新我的代码。将 Range 转换为 NSRange 时出错。如何在 swift 3 中做到这一点?

func nsRange(_ range : Range<String.Index>) -> NSRange 
    let utf16from = String.UTF16View.Index(range.lowerBound, within: utf16)
    let utf16to   = String.UTF16View.Index(range.upperBound,   within: utf16)
    return NSRange(location: utf16.startIndex.distanceTo(utf16from), length: utf16from.distanceTo(utf16to))

【问题讨论】:

***.com/a/30404532/1187415 具有 Swift 1.2、2 和 3 的转换方法。 ... 对于 Swift 4。 【参考方案1】:

Xcode 11 • Swift 5.1

import Foundation

extension RangeExpression where Bound == String.Index  
    func nsRange<S: StringProtocol>(in string: S) -> NSRange  .init(self, in: string) 


let string = "Hello USA ?? !!! Hello World !!!"
if let nsRange = string.range(of: "Hello World")?.nsRange(in: string) 
    (string as NSString).substring(with: nsRange) //  "Hello World"

也可以创建对应的nsRange(of:)方法扩展StringProtocol

extension StringProtocol 
    func nsRange<S: StringProtocol>(of string: S, options: String.CompareOptions = [], range: Range<Index>? = nil, locale: Locale? = nil) -> NSRange? 
        self.range(of: string,
                   options: options,
                   range: range ?? startIndex..<endIndex,
                   locale: locale ?? .current)?
            .nsRange(in: self)
    
    func nsRanges<S: StringProtocol>(of string: S, options: String.CompareOptions = [], range: Range<Index>? = nil, locale: Locale? = nil) -> [NSRange] 
        var start = range?.lowerBound ?? startIndex
        let end = range?.upperBound ?? endIndex
        var ranges: [NSRange] = []
        while start < end,
            let range = self.range(of: string,
                                   options: options,
                                   range: start..<end,
                                   locale: locale ?? .current) 
            ranges.append(range.nsRange(in: self))
            start = range.lowerBound < range.upperBound ? range.upperBound :
            index(range.lowerBound, offsetBy: 1, limitedBy: endIndex) ?? endIndex
        
        return ranges
    


let string = "Hello USA ?? !!! Hello World !!!"

if let nsRange = string.nsRange(of: "Hello World") 
    (string as NSString).substring(with: nsRange) //  "Hello World"

let nsRanges = string.nsRanges(of: "Hello")
print(nsRanges)   // "[0, 5, 19, 5]\n"

【讨论】:

那个 swift 3 代码是错误的检查:developer.apple.com/documentation/swift/string.utf16view

以上是关于如何在 NSRange 中转换范围? [复制]的主要内容,如果未能解决你的问题,请参考以下文章

NSRegularExpression如何让NSRange超出范围?

如何在 Swift 中创建范围?

如何从 NSRange 中提取整数值?

如何将 C++ 位集中的位范围子集转换为数字? [复制]

NSRange 在 for 循环中改变自身

View Controller 中的两个 TextField 设置为委托,导致应用崩溃,NSRange、范围或索引越界