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

String 如何在swift2中找到一个字符串在另一个字符串中的所有位置?,string,swift,String,Swift,我可以在我的字符串“ATGGACGTGAGCTGATCGATGGCTGAATGAAAA”中找到字符串“ATG”的第一个位置(即索引范围是0..,这是有意义的,因为,rangeOfString: 查找并返回接收器中给定字符串的第一次出现的范围 如果要查找所有出现的字符串,可以循环,直到rangeOfString:返回nil,然后每次将字符串修剪到匹配范围之后。当然,您必须跟踪原始字符串中的位置并转置索引。欢迎使用 这将是一个很好的编程练习。我建议你把它作为一个学习项目 编写一个函数,该函数接受要搜

我可以在我的字符串“ATGGACGTGAGCTGATCGATGGCTGAATGAAAA”中找到字符串“ATG”的第一个位置(即索引范围是0..,这是有意义的,因为,
rangeOfString:

查找并返回接收器中给定字符串的第一次出现的范围

如果要查找所有出现的字符串,可以循环,直到
rangeOfString:
返回nil,然后每次将字符串修剪到匹配范围之后。当然,您必须跟踪原始字符串中的位置并转置索引。

欢迎使用

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

编写一个函数,该函数接受要搜索的字符串和要搜索的字符串,并返回NSRange对象的可选数组。如果未找到任何匹配项,则可选数组将为零。或者,您也可以始终返回一个数组,但如果找不到该字符串,则该数组将包含0个NSRange对象

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

编辑:
一种优雅的方法是将其作为
String
类的扩展。这样,您就可以像使用
String
s的内置功能一样使用新方法。

您可以使用
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)]
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 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)]
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的本机
范围
类型

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=“atggacgtgagctgatcgatcgatggctgaatgaaaa”
让searchstr=“ATG”
做{
//创建正则表达式。
让regex=try NSRegularExpression(模式:searchstr,选项:[])
//使用正则表达式获取NSTextCheckingResult的数组。
//使用map从每个结果中提取范围。
让fullStringRange=mystr.nsRange(from:mystr.startIndex..

注释

  • 此方法有其局限性。如果要搜索的字符串是简单文本,但字符串包含符号(如
    “+*()[]。{}?\^$”
    ),则可以如果在正则表达式中有特殊含义,则这将无法按预期工作。您可以预处理搜索字符串以添加转义符以使这些字符的特殊含义无效,但这可能会带来更多麻烦
  • mystr
    “AAAA”
    并且
    searchstr
    “AA”
    时,可以证明另一个限制。在这种情况下,只能找到两次字符串。中间的
    AA
    将找不到,因为它以第一个范围的一部分字符开头
扩展字符串{
公共函数范围字符串(searchString:String,选项:NSStringCompareOptions=[],searchRange:Range?=nil)->[Range]{
如果let range=rangeOfsString(searchString,options:options,range:searchRange){
让nextRange=Range(开始:Range.endIndex,结束:self.endIndex)
return[range]+rangesOfString(searchString,searchRange:nextRange)
}否则{
返回[]
}
}
}

修剪字符串效率低下。(它在运行时会创建一系列新的字符串对象。)最好使用rangeOfString版本,该版本采用我的答案中概述的搜索范围。这是
NSRegularExpression
的一个很好的干净用法(投票)。但是,如果let
(Swift 1.2)或
do
(Swift 2)在外部不可访问,则
ranges
变量的作用域不限于
的大括号吗?为了使其有用,我认为您需要将ranges设置为
[NSRange]类型的数组?
并在作用域的外部级别对其进行定义。为什么不编辑您的答案以反映更改?这对OP和本线程的未来读者都会更有帮助。另一个问题:在第三个项目符号中,您建议添加
var ranges=[NSRange]()
。它分配一个新的空NSRange对象数组,然后由调用
matcheinstall
返回的数组替换。创建被替换的空范围没有意义。最好使用
var ranges=[NSRange]!
将其设为隐式展开可选,但不要创建空数组。这样可以保存一次性对象创建。好吧,您必须以某种方式处理错误情况。您可以在知道范围良好时使用范围(我的原始版本),您可以给
范围
一个默认值(我的第二个版本),您可以使用可选选项并选中它,也可以在错误情况下(我的最新版本)为
范围指定一个值。这在一种不使用变音符号的语言中起作用,例如在希伯来语中,所有的变音符号,如果你试图在一个长段落的末尾找到某个东西,它将找不到,因此最好使用
mystr.unicodeScalars.count
来计算单个unicode字符,而不仅仅是字形。这不是问题的答案。@SeanVikoren,我不同意。我提供了一个解决方案的大纲。事实上,我已经解释了如何做到这一点。我认为OP会从自己实施解决方案中学到更多,而不是给出完整的解决方案。这实际上是尽可能直接地回答问题。请参阅:@SeanVikoren,引用该链接:“任何能让提问者朝着正确方向前进的答案都是有帮助的,但一定要提到任何限制