检查字符串中字符串的非第一个实例
Check non-first instance of string in string
因此,我在另一个字符串中获取字符串实例的方法是使用此字符串 class 扩展名:
func indexOf(target: String) -> Int? {
let range = (self as NSString).range(of: target)
guard range.toRange() != nil else {
return nil
}
return range.location
}
但是,现在我正在寻找一种方法来获取字符串中字符串的第 n 个实例。例如,如果我想获取 "Houses on the show House house strange people." 中 "House" 的第三个实例的索引。我该怎么做?
直接在 Swift String
上运行的可能解决方案,
不桥接到 NSString
(并且不创建临时子字符串):
extension String {
func index(of target: String, instance: Int = 1) -> Int? {
precondition(!target.isEmpty)
precondition(instance > 0)
var found = 0 // Number of occurrences found so far.
var pos = startIndex // Current search position.
// Search for next occurrence of `target`.
while let r = range(of: target, range: pos..<endIndex) {
found += 1
// Are we done?
if found == instance {
// Distance in # of characters:
return distance(from: startIndex, to: r.lowerBound)
}
// Continue search after this occurrence.
pos = r.upperBound
}
return nil
}
}
示例:
let bStr = "Houses on the show Dr. House's PlayHouse house strange people"
let ls = "House"
if let idx = bStr.index(of: ls, instance: 3) {
print(idx) // 35
}
我喜欢 Martin R 的回答,但我发现递归表达式更直观。在我的实现中,我们实际上 return 范围(作为可选):
extension String {
typealias SRange = Range<String.Index>
func range(of target:String, options:String.CompareOptions, nth:Int) -> SRange? {
func helper(hnth:Int, range:SRange) -> SRange? {
let r = self.range(of: target, options: options, range: range)
if let r = r, hnth < nth {
return helper(hnth:hnth+1, range:r.upperBound..<self.endIndex)
}
return r
}
return helper(hnth:1, range: self.startIndex..<self.endIndex)
}
}
如果目标字符串 nth
存在,则 return 是一个 Swift 范围,否则 nil
。这是一个测试:
let s = "Houses on the show House house strange people."
let targ = "House"
let r = s.range(of: targ, options: .caseInsensitive, nth: 3)
// now r is an Optional wrapping 25..<30
因此,我在另一个字符串中获取字符串实例的方法是使用此字符串 class 扩展名:
func indexOf(target: String) -> Int? {
let range = (self as NSString).range(of: target)
guard range.toRange() != nil else {
return nil
}
return range.location
}
但是,现在我正在寻找一种方法来获取字符串中字符串的第 n 个实例。例如,如果我想获取 "Houses on the show House house strange people." 中 "House" 的第三个实例的索引。我该怎么做?
直接在 Swift String
上运行的可能解决方案,
不桥接到 NSString
(并且不创建临时子字符串):
extension String {
func index(of target: String, instance: Int = 1) -> Int? {
precondition(!target.isEmpty)
precondition(instance > 0)
var found = 0 // Number of occurrences found so far.
var pos = startIndex // Current search position.
// Search for next occurrence of `target`.
while let r = range(of: target, range: pos..<endIndex) {
found += 1
// Are we done?
if found == instance {
// Distance in # of characters:
return distance(from: startIndex, to: r.lowerBound)
}
// Continue search after this occurrence.
pos = r.upperBound
}
return nil
}
}
示例:
let bStr = "Houses on the show Dr. House's PlayHouse house strange people"
let ls = "House"
if let idx = bStr.index(of: ls, instance: 3) {
print(idx) // 35
}
我喜欢 Martin R 的回答,但我发现递归表达式更直观。在我的实现中,我们实际上 return 范围(作为可选):
extension String {
typealias SRange = Range<String.Index>
func range(of target:String, options:String.CompareOptions, nth:Int) -> SRange? {
func helper(hnth:Int, range:SRange) -> SRange? {
let r = self.range(of: target, options: options, range: range)
if let r = r, hnth < nth {
return helper(hnth:hnth+1, range:r.upperBound..<self.endIndex)
}
return r
}
return helper(hnth:1, range: self.startIndex..<self.endIndex)
}
}
如果目标字符串 nth
存在,则 return 是一个 Swift 范围,否则 nil
。这是一个测试:
let s = "Houses on the show House house strange people."
let targ = "House"
let r = s.range(of: targ, options: .caseInsensitive, nth: 3)
// now r is an Optional wrapping 25..<30