Reputation: 1644
I'm trying to capture a wind description from a METAR weather report (downloaded from http://weather.noaa.gov/pub/data/observations/metar/cycles/) and get the components of the wind from that block if it matches. The regular expression is @"^([0-9]{3}|VRB)([0-9]{2,3})G?([0-9]{2,3})?(KT|MPS|KMH)"
.
I'm using the PDRegex library for enumerating the captured matches into an array. (The PDRegex library can be found on https://github.com/carlbrown/RegexOnNSString/blob/master/RegexOnNSString/NSString%2BPDRegex.m)
These are the applicable lines in my code:
word = @"16008KT"; //test block
NSArray *matches = [word stringsByExtractingGroupsUsingRegexPattern:@"^([0-9]{3}|VRB)([0-9]{2,3})G?([0-9]{2,3})?(KT|MPS|KMH)"];
When stringsByExtractingGroupsUsingRegexPattern
(a PDRegex method) is called and matches, it crashes at line 62 of NSString+PDRegex
. This is the line of PDRegex where the app crashes:
NSString *matchedString=[self substringWithRange:[result rangeAtIndex:i]];
And this is the crash report:
Terminating app due to uncaught exception 'NSRangeException', reason: '-[__NSCFString substringWithRange:]: Range or index out of bounds'
Upvotes: 0
Views: 889
Reputation: 75222
It's probably because of the anchor (^
). You're telling it to match the pattern only if it's at the beginning of the line. (Or at the beginning of the whole string if it's not in multiline mode, but it looks like multiline mode is the default.)
If you want to make sure you're matching a real wind description and not a part of some longer string that happens to look like one (e.g. foo12307KTbar
), you can surround it with word boundaries:
\b([0-9]{3}|VRB)([0-9]{2,3})G?([0-9]{2,3})?(KT|MPS|KMH)\b
In Objective-C string literal form, I believe that would be:
@"\\b([0-9]{3}|VRB)([0-9]{2,3})G?([0-9]{2,3})?(KT|MPS|KMH)\\b"
Upvotes: 1
Reputation: 1644
I solved the problem by adding the following check above the problematic line:
if ([result rangeAtIndex:i].length!=0)
The problem occured because not all string parts in parentheses were matched, those unmatched ranges were out of range of the original 'word' string.
Upvotes: 2
Reputation: 2678
It seems your calling the range of out index, so make sure that the index i in the
NSString *matchedString=[self substringWithRange:[result rangeAtIndex:i]]; is defined
Upvotes: 1