This introduction to regular expressions teaches you the basics of regular expressions and how to use them.
This is a companion discussion topic for the original entry at https://www.raywenderlich.com/5767-an-introduction-to-regular-expressions
This introduction to regular expressions teaches you the basics of regular expressions and how to use them.
Hi
Just wanted to thank you for the tutorial. It’s awesome.
Also thank you for highligtMatches functions it’s toooo goood.
On my own could not have made it. You guys rocks
Cheers. Nanu Jogi
@nanujogi Really glad to hear it helped so much. Take care and keep up the good work! :]
Hello, thank you for really great tutorial for iOS beginners! Maybe I have find bug in function listGroups(). I have tried it in Playground this way:
let person = "54 male Russell Crowe"
listGroups(for: "([0-9]+)\\s?(male|female)?\\s?", inString: person)
let person2 = "54 Sandra Bullock"
listGroups(for: "([0-9]+)\\s?(male|female)?\\s?", inString: person2)
By the second usage, Playground wrote: Fatal error: Unexpectedly found nil while unwrapping an Optional value because (male|female)? was return nil for let range = Range(match.range(at: group), in: string)
I have changed
let range = Range(match.range(at: group), in: string)!
groupMatches.append(String(string[range]))
for
if let range = Range(match.range(at: group), in: string) {
groupMatches.append(String(string[range]))
} else {
groupMatches.append("")
}
Is it correct reasoning? I am programming in PHP and actually reading iOS Apprentice.
@tomelliott Can you please help with this when you get a chance? Thank you - much appreciated! :]
Hi @internetstream, you are right that the listGroups
function won’t work in the example above.
The reason is because your regex contains the group (male|female)?
, which is matched zero or more times. So when the text ‘male’ or ‘female’ is not present in the text, the regex engine is returning a capture group with a length of 0 and a location of NSNotFound.
You are also correct that guarding against this using if let
will work. Although if your case I think I would also make sure to specifically guard against the location being NSNotFound as well.
Finally, one thing I should probably mention as well if you want to make this generic… The result of NSRegularExpression.matches(in:options:range:)
returns the regex match as the first element in the array, and any Groups matched from element 1 onwards. So you should modify the function to start from index 1 not 0 if you only want groups.
I’ve tidied up ViewController.listGroups(for:inString:)
to make it more generically applicable:
func listGroups(for pattern: String, inString string: String) -> [String] {
guard let regex = try? NSRegularExpression(pattern: pattern, options: []) else {
return []
}
let range = NSRange(string.startIndex..., in: string)
let matches = regex.matches(in: string, options: [], range: range)
var groupMatches: [String] = []
for match in matches {
let numberOfRangesInMatch = match.numberOfRanges
for rangeIndex in 1..<numberOfRangesInMatch {
let range = match.range(at: rangeIndex);
if range.location != NSNotFound {
if let rangeInString = Range(range, in: string) {
groupMatches.append(String(string[rangeInString]))
}
}
}
}
return groupMatches
}
Hope that helps!
Hello @tomelliott, thanks a lot! Helped a lot. Have a nice day
This tutorial is more than six months old so questions are no longer supported at the moment for it. Thank you!