Reputation: 123
Hello I am having trouble using the Non-Capture group feature of regex in NSRegularExpressions
Heres some code to capture matches:
func matches(for regex: String, in text: String) -> [String] {
do {
let regex = try NSRegularExpression(pattern: regex);
let results = regex.matches(in: text,
range: NSRange(text.startIndex..., in: text));
return results.map {
String(text[Range($0.range, in: text)!]);
};
} catch let error {
print("invalid regex: \(error.localizedDescription)")
return [];
};
};
So now moving onto the regex, I have a string of text that is in the form workcenter:WDO-POLD
should be very easy to make this work but the regex string ((?:workcenter:)(.{0,20}))
does not return what I need
I get no errors on running but I get a return of the same string that I input - I am trying to retrieve the value that would be after workcenter:
which is (.{0,20})
Upvotes: 2
Views: 399
Reputation: 318794
The first problem is with your regular expression. You do not want the outer capture group. Change your regular expression to:
(?:workcenter:)(.{0,20}) <-- outer capture group removed
The next problem is with how you are doing the mapping. You are accessing the full range of the match and not the desired capture group. Since you have a generalized function for handling any regular expression, it's hard to deal with all possibilities but the following change solves your immediate example and should work with regular expressions that have no capture group as well as those with one capture group.
Update your mapping line to:
return results.map {
regex.numberOfCaptureGroups == 0 ?
String(text[Range($0.range, in: text)!]) :
String(text[Range($0.range(at: 1), in: text)!])
}
This checks how many capture groups are in your regular expression. If none, it returns the full match. But if there is 1 or more, it returns just the value of the first capture group.
You can also get your original mapping to work if you change your regular expression to:
(?<=workcenter:)(.{0,20})
There's a much simpler solution here.
You have a lot of extra groups. Remove the outermost and no need for the non-capture group. Just use workcenter:(.{0,20})
. Then you can reference the desired capture group with $1
.
And no need for NSRegularExpression
in this case. Use a simple string replacement.
let str = "workcenter:WDO-POLD"
let res = str.replacingOccurrences(of: "workcenter:(.{0,20})", with: "$1", options: .regularExpression)
This gives WDO-POLD
.
Upvotes: 2