假设我有字符串"blabla[R]bla[R]blaaa[R]blabla[R]bla[R]bla"
。
常规replacingOccurrences
替换所有出现的内容。我只想替换3。
newString = myString.replacingOccurrences(of: "[R]", with: "(X)")
得出结果"blabla(X)bla(X)blaaa(X)blabla[R]bla[R]bla"
。
答案 0 :(得分:4)
您可以获取该字符串的前3个范围,然后以相反的顺序迭代范围,以替换子范围:
var string = "blabla[R]bla[R]blaaa[R]blabla[R]bla[R]bla"
var ranges: [Range<String.Index>] = []
var start = string.startIndex
while start < string.endIndex,
let range = string.range(of: "[R]", range: start..<string.endIndex) {
ranges.append(range)
start = range.upperBound
if ranges.count == 3 { break }
}
for range in ranges.reversed() {
string.replaceSubrange(range, with: "(X)")
}
print(string) // blabla(X)bla(X)blaaa(X)blabla[R]bla[R]bla
答案 1 :(得分:1)
这是String的有用扩展,它为count
添加了replacingOccurrences
参数。这包括对范围和选项(例如,向后)的支持。
extension String {
func replacingOccurrences<Target, Replacement>(of target: Target, with replacement: Replacement, count: Int, options: String.CompareOptions = [], range searchRange: Range<String.Index>? = nil) -> String where Target : StringProtocol, Replacement : StringProtocol {
var matches = [Range<String.Index>]()
var sRange = searchRange ?? Range(startIndex..<endIndex)
while matches.count < count && !sRange.isEmpty {
if let mRange = range(of: target, options: options, range: sRange, locale: nil) {
matches.append(mRange)
if options.contains(.backwards) {
sRange = Range(sRange.lowerBound..<mRange.lowerBound)
} else {
sRange = Range(mRange.upperBound..<sRange.upperBound)
}
} else {
break
}
}
var res = self
for range in matches.sorted(by: { $0.lowerBound > $1.lowerBound }) {
res.replaceSubrange(range, with: replacement)
}
return res
}
}
let test = "blabla[R]bla[R]blaaa[R]blabla[R]bla[R]bla"
let res1 = test.replacingOccurrences(of: "[R]", with: "(x)", count: 3)
print(res1)
let res2 = test.replacingOccurrences(of: "[R]", with: "(x)", count: 3, options: [ .backwards ])
print(res2)
输出:
blabla(x)bla(x)blaaa(x)blabla [R] bla [R] bla
blabla [R] bla [R] blaaa(x)blabla(x)bla(x)bla