2

I'm trying to check if some email address is correct with the following code :

NSPredicate *regexMail = [NSPredicate predicateWithFormat:@"SELF MATCHES '.*@.*\..*'"];
if([regexMail evaluateWithObject:someMail])
... 

But the "\." doesn't seem to work since the mail "smith@company" is accepted. Besides, I have the following warning : "Unknown escape sequence"

Edit :

I'm programming in Objective-C for iPhone.

Thanks

Yoot
  • 43
  • 4
  • What regex library are you using? Which programming language? – Bork Blatt Jul 05 '10 at 13:31
  • Sorry, I forgot to mentionned that xD It's Objective-C for iPhone programming. – Yoot Jul 05 '10 at 14:07
  • Apart from the fact that matching an e-mail address with a regex is really difficult, there's no reason why there would have to be a . after the @. For instance, postmaster@com is probably a valid e-mail address. – JeremyP Jul 05 '10 at 16:28
  • possible duplicate of [What is the best regular expression for validating email addresses?](http://stackoverflow.com/questions/201323/what-is-the-best-regular-expression-for-validating-email-addresses) – Brad Mace Jul 09 '11 at 04:29

8 Answers8

13

This is the regular expression used by the iOS Mail application to validate an email address:

^[[:alnum:]!#$%&’*+/=?^_`{|}~-]+((\.?)[[:alnum:]!#$%&’*+/=?^_`{|}~-]+)*@[[:alnum:]-]+(\.[[:alnum:]-]+)*(\.[[:alpha:]]+)+$

And here is a copy/paste ready function using this regular expression to validate an email address in Objective-C:

BOOL IsValidEmail(NSString *email)
{
    // Regexp from -[NSString(NSEmailAddressString) mf_isLegalEmailAddress] in /System/Library/PrivateFrameworks/MIME.framework
    NSString *emailRegex = @"^[[:alnum:]!#$%&'*+/=?^_`{|}~-]+((\\.?)[[:alnum:]!#$%&'*+/=?^_`{|}~-]+)*@[[:alnum:]-]+(\\.[[:alnum:]-]+)*(\\.[[:alpha:]]+)+$";
    NSPredicate *emailPredicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", emailRegex];
    return [emailPredicate evaluateWithObject:email];
}
0xced
  • 25,219
  • 10
  • 103
  • 255
  • `john.doe@yahoo` is valid with this one – Rad'Val Apr 18 '12 at 11:38
  • Oops, good catch! I forgot to escape `.` with `\.` The regular expression is now fixed. – 0xced Apr 19 '12 at 09:29
  • 1
    I'm very bad at regex, so I was looking for a "ready to use" Regex. But this one (using NSPredicate regex implementation) has a major problem: try to validate this string: @"asdkfjaskdjfakljsdfasdkfjaskdjfakljsdfasdkfjaskdjfakljsdfasdkfjaskdjfakljsdf"and you'll see it never ends. – Altimac Jan 30 '15 at 15:37
6

You cannot correctly validate an email address with regular expressions alone. A simple search will show you many articles discussing this. The problem lies with the nature of DNS: there are too many possible domain names (including non-english and Unicode domains), you cannot correctly validate them using a regex. Don't try.

The only correct way to determine if an email address is valid is to send a message to the address with a unique URL that identifies the account associated with the email, for the user to click. Anything else will annoy your end-user.

Community
  • 1
  • 1
Craig Trader
  • 15,507
  • 6
  • 37
  • 55
  • Yes, you're right, I'm only trying to do a simple check, just to see if the mail looks like "name@company.com" with "@" and "." – Yoot Jul 05 '10 at 14:06
  • In which case `..*[@]..*[.]..*` should cover your needs. I use `..*` to match at least one character, because `.+`, while more direct, isn't supported by all RegEx libraries. I use `[@]` and `[.]` because they will match a single character, without needing to deal with backslashes and double-backslashes for escaping a single character. – Craig Trader Jul 05 '10 at 15:12
3

Here's a working example, with a slightly more appropriate pattern (although it's not perfect, as others have mentioned):

NSString* pattern = @"[A-Z0-9a-z._%+-]+@[A-Za-z0-9.-]+\\.[A-Za-z]{2,4}";
NSPredicate* predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", pattern];
if ([predicate evaluateWithObject:@"johndoe@example.com"] == YES) {
  // Match
} else {
  // No Match
}
Nathan de Vries
  • 15,481
  • 4
  • 49
  • 55
  • Still the same problem here with the caracter "." "johndoe@example" is matched but it shouldn't be. – Yoot Jul 06 '10 at 08:27
2

I guess it should be \\., since \ itself should be escaped as well.

Anton Gogolev
  • 113,561
  • 39
  • 200
  • 288
  • Already tried that, the warning disapeared, but the regex didn't work anyway. Will try the regex below. Thanks – Yoot Jul 05 '10 at 13:55
2

This page has a good explanation of using regular expressions to validate email, as well as some regexes:

http://www.regular-expressions.info/email.html

Their expression:

[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?

Seems to be the best tradeoff between thoroughness and correctness.

FrustratedWithFormsDesigner
  • 26,726
  • 31
  • 139
  • 202
0

try putting double slash instead of one slash. that's what might the Unknown escape sequence mean.

here is a website that can help you understand how to use regex: http://www.wellho.net/regex/java.html

or just find the appropriate regex for email address here: http://regexlib.com/DisplayPatterns.aspx?cattabindex=0&categoryId=1

Saher Ahwal
  • 9,015
  • 32
  • 84
  • 152
0

I think youre looking for this. Its a quite comprehensive listing of different regexps and a list of mail addresses for each, stating if the regexp was successful or not.

Mizipzor
  • 51,151
  • 22
  • 97
  • 138
0

Copy paste solution (I added capital letters for the first example):

We get a more practical implementation of RFC 5322 if we omit the syntax using double quotes and square brackets. It will still match 99.99% of all email addresses in actual use today. Source

[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?
  NSString * derivedStandard = @"[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\\.[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+)*@(?:[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?\\.)+[A-Za-z0-9](?:[A-Za-z0-9-]*[A-Za-z0-9])?";
  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", derivedStandard];
  BOOL isValid = [predicate evaluateWithObject:emailAddress];

//doesn't fail on ;)
@"asdkfjaskdjfakljsdfasdkfjaskdjfakljsdfasdkfjaskdjfakljsdfasdkfjaskdjfakljsdf"

For those who want to implement full RFC5322

The official standard is known as RFC 5322. It describes the syntax that valid email addresses must adhere to. You can (but you shouldn't--read on) implement it with this regular expression:

(?:[a-z0-9!#$%\&'*+/=?\^_`{|}~-]+(?:\.[a-z0-9!#$%\&'*+/=?\^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
  NSString *rfc5322 = @"(?:[a-z0-9!#$%\\&'*+/=?\\^_`{|}~-]+(?:\\.[a-z0-9!#$%\\&'*+/=?\\^_`{|}~-]+)*|\"(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21\\x23-\\x5b\\x5d-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])*\")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\\x01-\\x08\\x0b\\x0c\\x0e-\\x1f\\x21-\\x5a\\x53-\\x7f]|\\\\[\\x01-\\x09\\x0b\\x0c\\x0e-\\x7f])+)\\])";
  NSPredicate *predicate = [NSPredicate predicateWithFormat:@"SELF MATCHES %@", rfc5322];
  BOOL isValid = [predicate evaluateWithObject:emailAddress];

Above regexps you can test using online regular expression tester

Marek H
  • 5,173
  • 3
  • 31
  • 42