从字符串中获取重复子字符串的范围

Getting ranges of duplicate substrings from string

我对 NSRange、RangeExpression 和 NSAttributedString 函数失去了理智。我想要实现的是获取文本中出现的子字符串的所有范围。我最终得到的是:

let ranges: [NSRange] = textsToChange.compactMap { textToChange in
    if textToChange.result != nil {
        let strNumber: NSString = textFieldText as NSString
        return (strNumber).range(of: textToChange.text)
    } else {
        return nil
    }
}

我正在尝试将包含 TextToChange 对象的 textsToChange 数组映射到 NSRanges(TextToChange 只是一个包含三个字段的对象:文本、值和结果,它们都是一个字符串。然而,文本在这里是唯一重要的)通过查找每个对象映射到 NSRanges Textfield 文本中的文本。当 textsToChange 包含的每个文本都是唯一的时,一切都会按预期进行。但是,如果 textsToChange 包含任何重复项,假设:

“汽车”、“汽车”、“自行车”

然后,当有一个 textField 文本时:

“我有一辆黄色汽车,一辆蓝色汽车和一辆绿色自行车”

我得到范围 {15, 3}, {15, 3} 和 {43, 7} 因为 rangeOf returns 这个词第一次出现的范围。您是否知道任何简单的函数来获取给定子字符串的不同范围(例如:{15, 3}、{27, 3} 和 {43, 7})?

您可以尝试使用正则表达式...

func rangesForWords(_ words: [String], in text: String) -> [NSRange]? {
    
    var ranges: [NSRange] = []
    
    let ptrn = words.joined(separator: "|")
    
    do {
        let regex = try NSRegularExpression(pattern: ptrn, options: [.caseInsensitive])
        let items = regex.matches(in: text, options: [], range: NSRange(location: 0, length: (text as NSString).length))
        ranges = items.map{[=10=].range}
    } catch {
        // regex was bad?
        return nil
    }
    
    return ranges

}

也可以这样称呼:

let text: String = "I own a yellow car, a blue car and a green bicycle"

let words: [String] = [
    "car",
    "bicycle",
]
    
if let ranges = rangesForWords(words, in: text) {
    print(ranges)
} else {
    print("rangesForWords returned nil")
}
    

这给了我这个输出:

[{15, 3}, {27, 3}, {43, 7}]