I am struggling to modify captured value with regex.
For example, I wanna change "Hello, he is hero"
to "HEllo, HE is HEro"
using Regex.
I know there are ways to change this without regex, but it is just an example to show the problem. I actually use the regex instead of just he
, but I cannot provide it here. That is why using regex is required.
The code below somehow does not work. Are there any ways to make it work?
"Hello, he is hero".replacingOccurrences(
of: #"(he)"#,
with: "$1".uppercased(), // <- uppercased is not applied
options: .regularExpression
)
CodePudding user response:
You need to use your regex in combination with Range (range(of:)
) to find matches and then replace each found range separately
Here is a function as an extension to String that does this by using range(of:)
starting from the start of the string and then moving the start index to match from forward to after the last match. The actual replacement is done inside a separate function that is passed as an argument
extension String {
func replace(regex: String, with replace: (Substring) -> String) -> String {
var string = self
var startIndex = self.startIndex
let endIndex = self.endIndex
while let range = string.range(of: regex, options: [.regularExpression] , range: startIndex..<endIndex) {
string.replaceSubrange(range, with: replace(string[range]))
startIndex = range.upperBound
}
return string
}
}
Example where we do an case insensitive search for words starting with "he" and replace each match with the uppercased version
let result = "Hello, he is hero. There he is".replace(regex: #"(?i)\bhe"#) {
$0.uppercased()
}
Output
HEllo, HE is HEro. There HE is
CodePudding user response:
You can try NSRegularExpression
. Something like:
import Foundation
var sourceStr = "Hello, he is hero"
let regex = try! NSRegularExpression(pattern: "(he)")
let matches = regex.matches(in: sourceStr, range: NSRange(sourceStr.startIndex..., in: sourceStr))
regex.enumerateMatches(in: sourceStr, range: NSRange(sourceStr.startIndex..., in: sourceStr)) { (match, _, _) in
guard let match = match else { return }
guard let range = Range(match.range, in: sourceStr) else { return }
let sub = sourceStr[range]
sourceStr = sourceStr.replacingOccurrences(of: sub, with: sub.uppercased(), options: [], range: range)
}
print(sourceStr)
CodePudding user response:
this is the solution i can provide
var string = "Hello, he is hero"
let occurrence = "he"
string = string.lowercased().replacingOccurrences(
of: occurrence,
with: occurrence.uppercased(),
options: .regularExpression
)
print(string)