我可以通过使用下面的代码在myString“ATGGACGTGAGCTGATCGATGGCTGAAATGAAAA”中找到字符串“ATG”的第一个位置(即索引范围是0 ...< 3)。问题是如何找到“ATG”的所有位置,而不仅仅是myString中的第一个位置。
let stringRange = myString.rangeOfString("ATG")
答案 0 :(得分: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)]
Swift 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)]
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 {}
备注:
"+*()[].{}?\^$"
),那么您将没有问题,那么这将无法按预期工作。您可以预处理搜索字符串以添加转义以使这些字符的特殊含义无效,但这可能比它的价值更麻烦。mystr
为"AAAA"
且searchstr
为"AA"
时,可以证明另一个限制。在这种情况下,只能找到两次字符串。找不到中间 AA
,因为它以第一个范围内的字符开头。答案 1 :(得分: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 []
}
}
}
答案 2 :(得分:2)
欢迎来到SO。
这将是一个很好的编程练习。我建议你把它作为一个学习项目。
编写一个需要搜索字符串的函数和一个要搜索的字符串,并返回一个可选的NSRange对象数组。如果没有找到任何匹配项,则可选项将为nil。或者,您可以始终返回一个数组,但如果找不到该字符串,则包含0个NSRange对象。
让您的函数使用NSString
方法rangeOfString:options:range:
来搜索字符串。首先,您将搜索整个源字符串。找到第一个匹配项后,您将调整range
参数,以便仅在该事件发生后搜索源字符串的其余部分。
这样做的一种优雅方式是作为String
类的扩展。这样您就可以使用新方法,就像它是String
s。
答案 3 :(得分:1)
这是有道理的,因为according to the docs,rangeOfString:
查找并返回接收者中给定字符串第一次出现的范围。
如果你想找到所有的出现次数,你可以循环直到rangeOfString:
返回nil,并且每次将字符串修剪到匹配范围之后。当然,您必须跟踪原始字符串中的位置并转换索引。