如何在swift2中找到另一个字符串中一个字符串的所有位置?

VYT*_*VYT 10 string swift

我可以通过使用下面的代码在myString"ATGGACGTGAGCTGATCGATGGCTGAAATGAAAA"(即索引范围是0 .. <3)中找到字符串"ATG"的第一个位置.问题是如何找到"ATG"的所有位置,而不仅仅是myString中的第一个位置.

let stringRange = myString.rangeOfString("ATG")
Run Code Online (Sandbox Code Playgroud)

vac*_*ama 13

您可以NSRegularExpression用来查找字符串的所有匹配项:

Swift 1.2:

let mystr = "ATGGACGTGAGCTGATCGATGGCTGAAATGAAAA"
let searchstr = "ATG"
let ranges: [NSRange]

// Create the regular expression.
if let regex = NSRegularExpression(pattern: searchstr, options: nil, error: nil) {
    // Use the regular expression to get an array of NSTextCheckingResult.
    // Use map to extract the range from each result.
    ranges = regex.matchesInString(mystr, options: nil, range: NSMakeRange(0, count(mystr))).map {$0.range}

} else {
    // There was a problem creating the regular expression
    ranges = []
}

println(ranges)  // prints [(0,3), (18,3), (27,3)]
Run Code Online (Sandbox Code Playgroud)

斯威夫特2:

let mystr = "ATGGACGTGAGCTGATCGATGGCTGAAATGAAAA"
let searchstr = "ATG"
let ranges: [NSRange]

do {
    // Create the regular expression.
    let regex = try NSRegularExpression(pattern: searchstr, options: [])

    // Use the regular expression to get an array of NSTextCheckingResult.
    // Use map to extract the range from each result.
    ranges = regex.matchesInString(mystr, options: [], range: NSMakeRange(0, mystr.characters.count)).map {$0.range}
}
catch {
    // There was a problem creating the regular expression
    ranges = []
}

print(ranges)  // prints [(0,3), (18,3), (27,3)]
Run Code Online (Sandbox Code Playgroud)

Swift 3:使用Swift的原生Range类型.

let mystr = "ATGGACGTGAGCTGATCGATGGCTGAAATGAAAA"
let searchstr = "ATG"

do {
    // Create the regular expression.
    let regex = try NSRegularExpression(pattern: searchstr, options: [])

    // Use the regular expression to get an array of NSTextCheckingResult.
    // Use map to extract the range from each result.
    let fullStringRange = mystr.nsRange(from: mystr.startIndex ..< mystr.endIndex)          
    let matches = regex.matches(in: mystr, options: [], range: fullStringRange)
    let ranges = matches.map {$0.range}
    print(ranges)  // prints [(0,3), (18,3), (27,3)]
}
catch {}
Run Code Online (Sandbox Code Playgroud)

备注:

  • 这种方法有其局限性.如果您要搜索的字符串是简单文本,但如果字符串包含"+*()[].{}?\^$"在正则表达式中具有特殊含义的符号(例如),那么您将没有问题,那么这将无法按预期工作.您可以预处理搜索字符串以添加转义以使这些字符的特殊含义无效,但这可能比它的价值更麻烦.
  • 当另一个限制可以证明mystr"AAAA"searchstr"AA".在这种情况下,只能找到两次字符串.在中间的 AA,因为它有一个字符,第一个系列的一部分开始不会被发现.


Kla*_*aas 5

extension String {
    public func rangesOfString(searchString:String, options: NSStringCompareOptions = [], searchRange:Range<Index>? = nil ) -> [Range<Index>] {
        if let range = rangeOfString(searchString, options: options, range:searchRange) {

            let nextRange = Range(start:range.endIndex, end:self.endIndex)
            return [range] + rangesOfString(searchString, searchRange: nextRange)
        } else {
            return []
        }
    }
}
Run Code Online (Sandbox Code Playgroud)


Dun*_*n C 1

欢迎来到SO。

这将是一个很好的编程练习。我建议你把它作为一个学习项目。

编写一个函数,该函数接受要搜索的字符串和要搜索的字符串,并返回一个可选的 NSRange 对象数组。如果没有找到任何出现的情况,则可选值为 nil。或者,您始终可以返回一个数组,但如果未找到该字符串,则让它包含 0 个 NSRange 对象。

让您的函数使用该NSString方法rangeOfString:options:range:来搜索字符串。首先,您将搜索整个源字符串。找到第一个匹配项后,您可以调整range参数以仅搜索该匹配项之后源字符串的其余部分。

编辑:

一个优雅的方法是作为类的扩展String。这样你就可以使用你的新方法,就好像它是 s 的内置功能一样String

  • 这不是问题的答案。 (24认同)
  • 这实际上就是尽可能直接地回答问题。请参阅:http://stackoverflow.com/help/how-to-answer (4认同)