1

I have an array of data from which I would like to extract rows containing numbers and numbers only. Examples on rows:

15, +2, ' ', 7, 9, +21

(The ' ' represents one or more whitespaces).

In this case I would like to extract only 15, 7 and 9. I use a predicate in the following way:

NSString *pattern = @"[^0-9]";
NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
if (![predicate evaluateWithObject:myStringToMatch])
// Extract ...

I have tested my pattern using an online regex tester and found that [^0-9] does match anything but the numbers 0-9. However when I run the above code it only matches the whitespaces and not the eg +2, which I am pretty sure that it should do. Just to clarify, myStringToMatch is an NSString object.

I have no clue why it doesn't match my pattern. Can anyone give me a hint on what I'm doing wrong?

Thanks.

2 Answers 2

5

You regex matches anything but a single digit. If you are going to match rows containing numbers and numbers only, you need a regex which will not match on rows containing non-numbers.

You can use the following regex: ^[0-9]+$. It matches one ore more (+) digits ([0-9]) in a row and nothing else (anchors ^ and $ ensure that).

Then, instead of filtering rows that don't match, you process only the rows that do:

if ([predicate evaluateWithObject:myStringToMatch])
// note the absence of negation operator
// Extract ...
2
  • Thank you very much. I might have misinterpreted the output of the regex validator then. Can you tell me the difference of having ^ before (^[0-9]) the digits vs inside ([^0-9])? Commented Mar 9, 2012 at 7:11
  • 1
    ^ as the very first and $ as the very last characters of the whole regex are so called anchors: regular-expressions.info/anchors.html. ^ as the first character in a character class is a different thing, it negates the class: [a] matches single character a, while [^a] matches any character except a: regular-expressions.info/charclass.html Commented Mar 9, 2012 at 10:20
2

No, your regex matches anything but a single digit.

You can use the following code to test if a string contains only digits:

NSRegularExpression *r = [NSRegularExpression regularExpressionWithPattern:@"^[0-9]+$" options:0 error:nil];

NSArray *result = [r matchesInString:s options:0 range:NSMakeRange(0, s.length)];

result will be empty for the strings :+2, ' ' and +21 and non empty for the following strings: 15, 7 and 9.

So your code can be changed into:

if ([r matchesInString:s options:0 range:NSMakeRange(0, s.length)].length) {
    // Extract ...
}

Also, you can use the same regex with the predicate if you would like.

1
  • Thanks for the answer as well, @sch. I found that in this particular case it was easier to just use an NSPredicate. Can you tell me pros/cons of NSRegularExpression vs NSPredicate. Is nsregex better when dealing with more complext regular expressions? Commented Mar 9, 2012 at 7:17

Not the answer you're looking for? Browse other questions tagged or ask your own question.