在替换字符串后检索范围的更好方法吗?
这是当前版本:
let username = "apple"
msgString = "{{user}} has an apple"
guard let range = msgString.range(of: "{{user}}") else { return }
msgString.replaceSubrange(range, with username)
userRange = msgString.range(of: username)
有什么更好的方法来获取用户名范围
答案 0 :(得分:1)
我建议您创建一个类来做您多次做的事情
在此类中,您可以使用replace方法获取stringRange和newReplacedString:
class StringService {
/** create an object to access every method because this class provides you services */
static let shared = StringService()
/** Service classes should not be available for creating instances */
private init () {}
func replace(mySting: String ,by: String, with: String) -> (String,Range<String.Index>?) {
var newString = ""
if let range = myString.range(of:by) {
newString.replaceSubrange(range,with:with)
return (newString,range)
}esle{
return ("",nil)
}
}
let replacedString = StringService.shared.replace(mySting: "myString is",
by: "is",
with: "was").0
if let replacedStringRange = StringService.shared.replace(mySting: "myString is",
by: "is",
with: "was").1 {
}
如果您想使用本机库,则可以使用:
"myString is".replacingOccurrences(of: "is",
with: "was",
options: .literal,
range: nil)
答案 1 :(得分:0)
两个功能:
replacingOccurrences...
返回一个新字符串并告知更改范围replaceOccurrences...
更改当前变量的值并通知更改范围实现这些目标的最佳位置是String
扩展名:
extension String {
func replacingOccurrences<T: StringProtocol>(of toReplace: T,
with newString: T,
options: String.CompareOptions = [],
range searchRange: Range<T.Index>? = nil,
completion: ((Range<T.Index>?, Range<T.Index>?) -> Void)) -> String {
let oldRange = range(of: toReplace)
let replacedString = replacingOccurrences(of: toReplace,
with: newString,
options: options,
range: searchRange)
let newRange = replacedString.range(of: newString)
completion(oldRange, newRange)
return replacedString
}
mutating func replaceOccurrences<T: StringProtocol>(of toReplace: T,
with newString: T,
options: String.CompareOptions = [],
range searchRange: Range<T.Index>? = nil,
completion: ((Range<T.Index>?, Range<T.Index>?) -> Void)) {
self = replacingOccurrences(of: toReplace,
with: newString,
options: options,
range: searchRange,
completion: completion)
}
}
用法:
let username = "apple"
var msgString = "{{user}} has an apple"
msgString.replaceOccurrences(of: "{{user}}", with: username) { (oldRange, newRange) in
print(oldRange)
print(newRange)
}
答案 2 :(得分:0)
让我们从您提供的代码的更正版本开始:
let username = "apple"
var msgString = "{{user}} has an apple"
guard let range = msgString.range(of: "{{user}}") else { return }
msgString.replaceSubrange(range, with: username)
在这里,我们在msgString
中将"{{user}}"
替换为"apple"
。问题是:"apple"
中的msgString
的范围是多少?
当您意识到我们已经知道答案时,解决方案很简单。它分为两个部分:
新范围从旧范围开始的同一位置开始。这就是说新范围的下限与旧范围的下限相同。我们已经知道那是什么了:range.lowerBound
。
新范围的长度是替换字符串的长度。表示为count
。
因此,所需范围是:
let newRange =
range.lowerBound..<msgString.index(range.lowerBound, offsetBy: username.count)
如果我们要做很多这样的事情,扩展String可能会很好。例如:
extension String {
mutating func replaceSubrangeAndReportNewRange (
_ bounds: Range<String.Index>, with s: String
) -> Range<String.Index> {
self.replaceSubrange(bounds, with:s)
return bounds.lowerBound..<self.index(bounds.lowerBound, offsetBy:s.count)
}
}
答案 3 :(得分:-1)
Swift 4.0
您可以使用replacingOccurrences
方法替换文本。
msgString.replacingOccurrences(of: "{{user}}", with: "apple", options: .literal, range: nil)
输出:
apple has an apple