Swift replace substring regex
Solution 1
You need to remove the ^
and $
anchors.
The ^
means start of string and $
means end of string (or line, depending on the options). That's why your first example works: in the first test string, the start of the string is really followed by your pattern and ends with it.
In the second test string, the pattern is found in the middle of the string, thus the ^...
can't apply. If you would just remove the ^
, the $
would apply on the second occurrence of the registration number and the output would be my car reg 1 - DD11 AAA my car reg 2 - XX
.
let myString = "my car reg 1 - DD11 AAA my car reg 2 - AA22 BBB"
let regex = try! NSRegularExpression(pattern: "([A-HK-PRSVWY][A-HJ-PR-Y])\\s?([0][2-9]|[1-9][0-9])\\s?[A-HJ-PR-Z]{3}", options: NSRegularExpression.Options.caseInsensitive)
let range = NSMakeRange(0, myString.count)
let modString = regex.stringByReplacingMatches(in: myString, options: [], range: range, withTemplate: "XX")
print(modString)
// Output: "my car reg 1 - XX my car reg 2 - XX"
Solution 2
Let's use a class extension to wrap this up in Swift 3 syntax:
extension String {
mutating func removingRegexMatches(pattern: String, replaceWith: String = "") {
do {
let regex = try NSRegularExpression(pattern: pattern, options: .caseInsensitive)
let range = NSRange(location: 0, length: count)
self = regex.stringByReplacingMatches(in: self, options: [], range: range, withTemplate: replaceWith)
} catch { return }
}
}
var phoneNumber = "+1 07777777777"
phoneNumber.removingRegexMatches(pattern: "\\+\\d{1,4} (0)?")
Results in 7777777777
(thus removing country code from phone number)
Solution 3
Swift 4.2 Updated
let myString = "my car reg 1 - DD11 AAA my car reg 2 - AA22 BBB"
if let regex = try? NSRegularExpression(pattern: "([A-HK-PRSVWY][A-HJ-PR-Y])\\s?([0][2-9]|[1-9][0-9])\\s?[A-HJ-PR-Z]{3}", options: .caseInsensitive) {
let modString = regex.stringByReplacingMatches(in: myString, options: [], range: NSRange(location: 0, length: myString.count), withTemplate: "XX")
print(modString)
}
Solution 4
Update for Swift 2.1:
var myString = "my car reg 1 - DD11 AAA my car reg 2 - AA22 BBB"
if let regex = try? NSRegularExpression(pattern: "([A-HK-PRSVWY][A-HJ-PR-Y])\\s?([0][2-9]|[1-9][0-9])\\s?[A-HJ-PR-Z]{3}", options: .CaseInsensitive) {
let modString = regex.stringByReplacingMatchesInString(myString, options: .WithTransparentBounds, range: NSMakeRange(0, myString.characters.count), withTemplate: "XX")
print(modString)
}
Solution 5
Warning
Do not use NSRange(location: 0, length: myString.count)
as all examples above quoted.
Use NSRange(myString.startIndex..., in: myString)
instead!
.count
will count newline characters like \r\n
as one character - this may result in a shortened, thus invalid, NSRange that does not match the whole string.
(.length should work)
jjc99
Updated on July 09, 2022Comments
-
jjc99 almost 2 years
I am attempting to use regular expression to replace all occurrences of UK car registrations within a string.
The following swift code works perfectly for a when the string matches the regex exactly as below.
var myString = "DD11 AAA" var stringlength = countElements(myString) var ierror: NSError? var regex:NSRegularExpression = NSRegularExpression(pattern: "^([A-HK-PRSVWY][A-HJ-PR-Y])\\s?([0][2-9]|[1-9][0-9])\\s?[A-HJ-PR-Z]{3}$", options: NSRegularExpressionOptions.CaseInsensitive, error: &ierror)! var modString = regex.stringByReplacingMatchesInString(myString, options: nil, range: NSMakeRange(0, stringlength), withTemplate: "XX") print(modString)
The result is
XX
However, the following does not work and the string is not modifed
var myString = "my car reg 1 - DD11 AAA my car reg 2 - AA22 BBB" var stringlength = countElements(myString) var ierror: NSError? var regex:NSRegularExpression = NSRegularExpression(pattern: "^([A-HK-PRSVWY][A-HJ-PR-Y])\\s?([0][2-9]|[1-9][0-9])\\s?[A-HJ-PR-Z]{3}$", options: NSRegularExpressionOptions.CaseInsensitive, error: &ierror)! var modString = regex.stringByReplacingMatchesInString(myString, options: nil, range: NSMakeRange(0, stringlength), withTemplate: "XX") print(modString)
The result is
my car reg 1 - DD11 AAA my car reg 2 - AA22 BBB
Can anyone give me any pointers?
-
onmyway133 about 8 yearsthe option that DarkDust mention is
AnchorsMatchLines
-
xxmbabanexx about 7 yearsfor some reason NSRegularExpression doesn't seem to be working in swift 3. How would you go about correcting this?
-
ablarg over 6 yearsuse of NSMakeRange generates
warning: Legacy Constructor Violation: Swift constructors are preferred over legacy convenience functions. (legacy_constructor)
in swiftlint -
Constantine almost 4 years@ablarg you can fix that by replacing the line with:
let range = NSRange(location: 0, length: self.count)