Created
January 14, 2020 18:08
-
-
Save illescasDaniel/678cfb3550bda20c9f7ebf8ca465b265 to your computer and use it in GitHub Desktop.
swift regular expression replace matches using transform
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| import Foundation | |
| extension String { | |
| func replacingOcurrences(ofPattern pattern: String, _ matchTransform: (NSTextCheckingResult) -> String) -> String { | |
| guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else { | |
| return self | |
| } | |
| var transformedCharacters: [Character] = [] | |
| var formatStringCurrentIndex = 0 | |
| let formatCharacters = [Character](self) | |
| regex.enumerateMatches(in: self, options: [], range: NSRange(self.startIndex..<self.endIndex, in: self)) { (match, _, _) in | |
| guard let match = match else { return } | |
| let transformedValue = matchTransform(match) | |
| let charactersRange = match.range.location..<(match.range.location + match.range.length) | |
| while formatStringCurrentIndex < charactersRange.lowerBound { | |
| transformedCharacters.append(formatCharacters[formatStringCurrentIndex]) | |
| formatStringCurrentIndex += 1 | |
| } | |
| transformedCharacters.append(contentsOf: transformedValue) | |
| formatStringCurrentIndex = charactersRange.upperBound | |
| } | |
| transformedCharacters.append(contentsOf: formatCharacters[formatStringCurrentIndex...]) | |
| return String(transformedCharacters) | |
| } | |
| } | |
| extension String { | |
| func replacingOcurrences(ofPattern pattern: String, _ matchValueTransform: (String) -> String) -> String { | |
| self.replacingOcurrences(ofPattern: pattern) { (match: NSTextCheckingResult) in | |
| guard let matchRange = Range(match.range, in: self) else { | |
| return self | |
| } | |
| let matchValue = String(self[matchRange]) | |
| return matchValueTransform(matchValue) | |
| } | |
| } | |
| } | |
| let dict: [String: Any] = [ | |
| "name": "Danielj7", | |
| "other": 2231237 | |
| ] | |
| let start = DispatchTime.now() | |
| print( | |
| "Me llamo {name}, tengo {other} años".replacingOcurrences(ofPattern: #"\{(\w+)\}"#) { (matchValue: String) in | |
| String(describing: dict[String(matchValue.dropFirst().dropLast())] ?? matchValue) | |
| } | |
| ) | |
| let end = DispatchTime.now() | |
| let nanoTime = end.uptimeNanoseconds - start.uptimeNanoseconds | |
| let timeInterval = Double(nanoTime) / 1_000_000_000 | |
| print(timeInterval) |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment