Reputation: 5801
I am trying to validate a string against the following regular expression:
[(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,20}]
The validation passes if it done using the numberOfMatches
method as follows:
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:@“[(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,20}]” options:0 error:&error];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:string options:0 range:NSMakeRange(0, string.length)];
BOOL status numberOfMatches == string.length;
If the validation is done using a NSPredicate
the validation fails:
NSPredicate *test = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", [(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,20}]];
BOOL status = [test evaluateWithObject:string];
What's the reason for this? I would like to do this using a NSPredicate
.
Upvotes: 0
Views: 210
Reputation: 56809
Surrounding your regex with []
is wrong, since all the content inside is interpreted as part of a character class. In your case:
[(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,20}]
It is a character class containing A-Z
, 0-9
, a-z
, {}()?=.,*
.
Since NSRegularExpression
is using ICU's regex library, it supports character class union, like in Java.
The correct regex should be:
^(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,20}$
Your first piece of code with NSRegularExpression
should be:
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:
@"^(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,20}$"
options:0
error:&error];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:string
options:0
range:NSMakeRange(0, string.length)];
BOOL status = numberOfMatches == 1;
Since the regex only matches when it matches the whole string, you will get at most 1 match.
Your second piece of code with NSPredicate
should be:
NSPredicate *test = [NSPredicate predicateWithFormat:
@"SELF MATCHES %@",
@"'^(?=.*[A-Z])(?=.*[0-9])(?=.*[a-z]).{6,20}$'"];
BOOL status = [test evaluateWithObject:string];
Note that apart from the escaping of \
which you have to do for the String object literal, you need to take care of another level of escaping for the string literal in predicate syntax (see the example). Luckily, we don't have to care about that here, since you don't use \
in your regex.
The regex should not be specified directly in the format string (like in the previous revision), since it will incur another level of escaping for format string syntax.
Upvotes: 1