Objective-c regex to check phone number [duplicate] - objective-c

This question already has answers here:
Closed 10 years ago.
Possible Duplicate:
A comprehensive regex for phone number validation
How to validate a phone number (NSString *) in objective-c? Rules:
minimum 7 digits
maximum 10 digits
the first digit must be 2, 3, 5, 6, 8 or 9
Thanks

You can use a regular expressions library (like RegexKit, etc), or you could use regular expressions through NSPredicate (a bit more obscure, but doesn't require third-party libraries). That would look something like this:
NSString *phoneNumber = ...;
NSString *phoneRegex = #"[235689][0-9]{6}([0-9]{3})?";
NSPredicate *test = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", phoneRegex];
BOOL matches = [test evaluateWithObject:phoneNumber];
If you're on iPhone, then iOS 4 introduced NSRegularExpression, which would also work. The NSPredicate approach works on both Mac and iPhone (any version).

Please don't use your own regex for the phone-number. Don't.
The format of phone numbers changes across the country, and your app might be used outside of your own country.
Instead, use what Apple provides, as Josh says. See here.

For those searching for phone extraction, you can extract the phone numbers from a text, for example:
NSString *userBody = #"This is a text with 30612312232 my phone";
if (userBody != nil) {
NSError *error = NULL;
NSDataDetector *detector = [NSDataDetector dataDetectorWithTypes:NSTextCheckingTypePhoneNumber error:&error];
NSArray *matches = [detector matchesInString:userBody options:0 range:NSMakeRange(0, [userBody length])];
if (matches != nil) {
for (NSTextCheckingResult *match in matches) {
if ([match resultType] == NSTextCheckingTypePhoneNumber) {
DbgLog(#"Found phone number %#", [match phoneNumber]);
}
}
}
}
`

The NSDataDetector class, available in iOS 4.0 and later, is a specialized subclass of NSRegularExpression that has explicit support for detecting phone numbers.

In iOS 4.0+ there are built in classes to do this, NSRegularExpression
In everything else you can either use a 3rd party RegEx library, or use an NSPredicate if your needs are narrow enough

Related

Apostrophes (') is not recognised in regular expression

I want a regular expression for first name that can contain
1)Alphabets
2)Spaces
3)Apostrophes
Exp: Raja, Raja reddy, Raja's,
I used this ^([a-z]+[,.]?[ ]?|[a-z]+[']?)+$ but it is failing to recognise Apostrophes (').
- (BOOL)validateFirstNameOrLastNameOrCity:(NSString *) inputCanditate {
NSString *firstNameRegex = #"^([a-z]+[,.]?[ ]?|[a-z]+[']?)+$";
NSPredicate *firstNamePredicate = [NSPredicate predicateWithFormat:#"SELF MATCHES[c] %#",firstNameRegex];
return [firstNamePredicate evaluateWithObject:inputCanditate];
}
May I recommand ^[A-Z][a-zA-Z ']* ?
// The NSRegularExpression class is currently only available in the Foundation framework of iOS 4
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression regularExpressionWithPattern:#"^[A-Z][a-zA-Z ']*" options:NSRegularExpressionAnchorsMatchLines error:&error];
NSUInteger numberOfMatches = [regex numberOfMatchesInString:searchText options:0 range:NSMakeRange(0, [string length])];
return numberOfMatches > 1;
^[A-Z] : Force start with a capital letter from A to Z
[a-zA-Z ']* : followed by any number of charactere that an be 'a' to 'z', 'A' to 'Z', space or simple quote
I think you are looking for a pattern like this: ^[a-zA-Z ']+$
However, this is pretty bad. What about umlauts, accents, and a whole lot other letters that are not part of the ASCII alphabet?
A better solution would be to allow any kind of letter from any language.
To do so you can use the Unicode "letter" category \p{L}, e.g. ^[\p{L}]+$.
.. or you could just drop that rule all together - as reasonably suggested.

Matching a regular expression with a string (file name)

I'm trying to differentiate between 2 files (in NSString format). As far as I know, this can be done by comparing and matching a regular expression. The format of the 2 jpg files which I have are:
butter.jpg
butter-1.jpg
My question is what regular expression can I write to match the 2 strings above? I've search and found an example expression, but I'm not sure how is it read and think it's wrong.
Here is my code:
NSString *exampleFileName = [NSString stringWithFormat:#"butter-1.jpg"];
NSString *regEx = #".*l{2,}.*";
NSPredicate *regExTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", regEx];
if ([regExTest evaluateWithObject:exampleFileName] == YES) {
NSLog(#"Match!");
} else {
NSLog(#"No match!");
}
EDIT:
I tried using the following:
NSString *regEx = #"[a-z]+-[0-9]+.+jpg";
to try to match:
NSString *exampleFileName = [NSString stringWithFormat:#"abcdefg-112323.jpg"];
Tested with:
abc-11.jpg (Match)
abcsdas-.jpg (No Match)
abcdefg11. (No Match)
abcdefg-3123.jpg (Match)
As of now it works, but I want to eliminate any chances that it might not, any inputs?
NSString *regEx = #"[a-z]+-[0-9]+.+jpg";
will fail for butter.jpg, as it needs to have one - and at least on number.
NSString *regEx = #"[a-z]+(-[0-9]+){0,1}.jpg";
and if you do
NSString *regEx = #"([a-z])+(?:-([0-9])+){0,1}.jpg";
You can access the informations you probably would like to have later as capture groups.
(...) |Capturing parentheses. Range of input that matched the parenthesized subexpression is available after the match.
and if you dont need capture groups
NSString *regEx = #"(?:[a-z])+(?:-[0-9]+){0,1}.jpg";
(?:...)| Non-capturing parentheses. Groups the included pattern, but does not provide capturing of matching text. Somewhat more efficient than capturing parentheses.
You can match an alphabetic character (in any language) using \p{L}. You can match a digit using \d. You need to escape the . because in a regular expression, . means “any character”.
Parsing a regular expression is expensive, so you should only do it once.
BOOL stringMatchesMyPattern(NSString *string) {
static dispatch_once_t once;
static NSRegularExpression *re;
dispatch_once(&once, ^{
re = [NSRegularExpression regularExpressionWithPattern:
#"^\\p{L}+-\\d+\\.jpg$" options:0 error:NULL];
}
return nil != [re firstMatchInString:string options:0
range:NSMakeRange(0, string.length)];
}

Finding 2 Capitalized Words in a Row NSString

I'm writing a Mac app that goes through an NSString, and adds all its word to an NSArray (by separating them based on whitespace). Now, I've got the whole system down, but I'm still having one little problem: names (first + last), are added as two different words, and that's bothersome to me.
I thought of a couple solutions to fix this. My best idea was to, before actually adding the words to the array, join two words in a row that are capitalized. Then, through an if statement, determine if a word has two capitals in it, and then split the word and add it as one word. However, I can't find a way to find 2 words in a row with capitals.
Should I be using RegexKitLite (which I'm not familiar with), for example, to find two capitalized words in a row? I've seen this question: Regexp to pull capitalized words not at the beginning of sentence and two adjacent words
which seems somehow related, but due to my lack of understand of regular expressions, I don't really know if this is exactly what I need.
I've also seen this: Separating NSString into NSArray, but allowing quotes to group words
which is also similar, yet not exactly adapted to my needs.
So, to conclude, does anyone know how to either join capitalized words in an NSString, or even better, how to find two capitalized words in a row in an NSString ?
If you're targeting iOS 4.0 or greater OR OS 10.7 you can use NSRegularExpression
NSError *error = NULL;
NSRegularExpression *regex = [NSRegularExpression
regularExpressionWithPattern:#"[A-Z]\\w*\\s[A-Z]\\w*"
options:nil
error:&error];
NSString *inputString = #"One two Three Four five six Seven Eight";
NSArray *stringsWithTwoCapitalizedWordsInARow = [regex
matchesInString:inputString
options:0
range:NSMakeRange(0, [string length])];
You'll get something like this
["Three Four", "Seven Eigth"]
You could just do a second pass on the resulting array after it has been loaded to append entries together that need to be joined.
Names are notoriously difficult to match with regular expressions alone, as it is not unheard of for names (first or last) to contain spaces themselves.
NSMutableArray* words = ...;
NSMutableArray* joinedWords = [NSMutableArray array];
for (int i=0; i < [words length]; i++)
{
NSString* currentLine = [words objectAtIndex:i];
bool capitalized = false;
bool capitalizedNext = false;
capitalized = isCap(currentLine); // Up to your discretion here
NSString* nextLine = nil;
// for the last entry
if (i+1 < [words length])
{
nextLine = [words objectAtIndex:i+1];
capitalizedNext = isCap(nextLine);
}
// Check if first letter is uppercase
if (capitalized == true && capitalizedNext == true)
{
[words replaceObjectAtIndex:i withObject:[NSString stringWithFormat:#"%# %#", currentLine, nextLine];
[words removeObjectAtIndex:i+1];
// Run test again on new version of the line
i--;
}
else
{
[joinedWords addObject:currentLine];
}
}
[A-Z][A-Za-z]* [A-Z][A-Za-z]*|[\S]*
http://rubular.com/r/DrOabOAfBr
I've written a regular expression for you. This regex will try to match a name first, then fall back to a word, so your job is as simple as feeding this into NSRegularExpression, and take all the matches as your words, or names joined.

How to check if string matches a regular expression in objective-c?

since regular exressions are not supported in Cocoa I find RegexKitLite very usefull.
But all examples extract matching strings.
I just want to test if a string matches a regular expression and get a Yes or No.
How can I do that?
I've used NSPredicate for that purpose:
NSString *someRegexp = ...;
NSPredicate *myTest = [NSPredicate predicateWithFormat:#"SELF MATCHES %#", someRegexp];
if ([myTest evaluateWithObject: testString]){
//Matches
}
Another way to do this, which is a bit simpler than using NSPredicate, is an almost undocumented option to NSString's -rangeOfString:options: method:
NSRange range = [string rangeOfString:#"^\\w+$" options:NSRegularExpressionSearch];
BOOL matches = range.location != NSNotFound;
I say "almost undocumented", because the method itself doesn't list the option as available, but if you happen upon the documentation for the Search and Comparison operators and find NSRegularExpressionSearch you'll see that it's a valid option for the -rangeOfString... methods since OS X 10.7 and iOS 3.2.
NSRegularExpression is another option:
http://developer.apple.com/library/ios/#documentation/Foundation/Reference/NSRegularExpression_Class/Reference/Reference.html
Use the -isMatchedByRegex: method.
if([someString isMatchedByRegex:#"^[0-9a-fA-F]+:"] == YES) { NSLog(#"Matched!\n"); }

Checking to see if an NSString contains characters from a different NSString

I am looking for a way to compare two strings and see if the second string contains a character (letter, number, other) listed in the first, let me explain:
For example: Imagine a password with only digits and "*" are allowed:
Reference chain (1): "*0123456789" NSString format, no NSArray
Work chain (2) = "156/15615=211" NSString format,
How do I know that my chain 2 contains 2 characters (/=) which are not in my chain 1?
To simplify the management letters allowed, I do not want to use NSArray to manage a chain for example a function call:
BOOL unauthorized_letter_found = check(work_chain, reference_chain);
You it must go through "for", NSPredicate, etc. ?
PS: I'm on MAC OS, not iOS so I can not use NSRegularExpression.
You could go with character sets, e.g. using -rangeOfCharacterFromSet: to check for the presence of forbidden characters:
NSCharacterSet *notAllowed = [[NSCharacterSet
characterSetWithCharactersInString:#"*0123456789"] invertedSet];
NSRange range = [inputString rangeOfCharacterFromSet:notAllowed];
BOOL unauthorized = (range.location != NSNotFound);
If you want to use an NSPredicate, you can do:
NSPredicate *predicate = [NSPredicate predicateWithFormat:#"SELF MATCHES '[0-9*]+'"];
if ([predicate evaluateWithObject:#"0*2481347*"]) {
NSLog(#"passes!");
} else {
NSLog(#"fails!");
}
This is using NSPredicate's built-in regular expression matching stuff. :)