What is wrong with this regex?
function validateEmail($email){
if (eregi("^([a-z]|[0-9]开发者_开发知识库|\.|-|_)+@([a-z]|[0-9]|\.|-|_)+\.([a-z]|[0-9]){2,3}$", $email, $arr_vars) &&
!eregi("(@.*@)|(\.\.)|(@\.)|(\.@)|(^\.)", $email, $arr_vars)){
return true;
}else{
return false;
}
}
When used:
$email = "hello@hello.info";
if (validateEmail($email) != 1){
//show error
}
It returns false and shows an error, whats wrong?
The {2,3}
at the end of your regex says to match only if that pattern matches at least 2, but no more than three characters. info
is a 4 character TLD.
There are other problems with your code as well, by the way:
First, your "allowed characters" lists are needlessly complex. Instead of ([a-z]|[0-9]|\.|-|_)
you could specify all the allowable characters in a single []
set, like [a-z0-9\.-_]
.
Second, the eregi()
function is deprecated as of PHP 5.3 (click that link and you'll see a massive warning about it). I think you should be using preg_match()
instead.
Third, anytime you see something like this:
if (condition) {
return true;
} else {
return false;
}
You can shorten that to just this:
return (condition);
The reason for this is that the (condition)
will return a boolean value, so when you drag it out, you're essentially saying this:
if (true) {
return true;
} else {
return false;
}
One last thing to note is that in most cases you don't really need to run a regex on an email address. It's usually better to just send a confirmation email to the address, and validate it if the addressee opens it and clicks a link in the email.
That said, there's nothing wrong with running a quick sanity check on the address to make sure that it's at least mailable.
In that case, though, you should just check that there is an @
character in the address somewhere (at at least the second position), with a .
character somewhere after at least one more character, and at least two non-.
characters after at .
.
The reason for this is that a proper regex to validate an email address according to the actual rules in the RFC describing them is hopelessly complex. People have made valiant attempts at creating such a regex, and they end up being literally pages long.
Hope that helps.
.info isn't 2 or three characters long. (The last part of your regex)
That said: Don't write your own email regex validator. It is more complicated than you think, and you will screw it up. For instance, this is a more accurate and advanced take on it from http://www.regular-expressions.info/email.html
(?:[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])+)\])
Find someone who provides a decent library instead.
For starters, if you're just looking for a list of possibles, ([a-z]|[0-9]|\.|-|_)
can be changed in to something simpler, such as [a-z0-9\._-]
That is a class that contains any of the values within the []'s.
And the actual problem is the {2,3} at the end, symbolizing 2-3 characters (your "info" suffix is 4 characters).
EDIT As an aside, I recommend a website such as regexlib.com where you can search through libraries of results. Also, RegExr is a useful website for testing patters and seeing the results in real-time.
First of all, ereg() and eregi() are deprecated in favour of preg_match() - so you shouldn't use them at all.
Besides that, the first regexp is simply incorrect. It assumes a TLD always has 2 or 3 characters, so it doesn't work with some newer TLDs like .info, .aero, .travel etc.
Additionally, the +
character is perfectly valid in the local part of an email address (e.g. me+something@example.com
) - same applies for things like umlauts which would fail your regex.
([a-z]|[0-9]|\.|-|_)
also doesn't make much sense, there's a much shorter ans less confusing way to write that: ([a-z0-9._-])
Actually, using regular expressions to validate email addresses is not a good thing. The proper way would be extracting the domain (everything after @
) part from the address and then checking if there are valid DNS records (usually MX, but A also do the job if there are no MX records). Another step would be testing if there's actually a mail server listening on the IP the DNS record points to or even asking that server if it knows the recipient (not all server might give out such information without actually trying to sen an email htough).
One of the only ways to check if an email address is valid is to actually send an email to it.
.
Also, your checker would fail for any addresses that have a '
in them, eg : Ian.O'Connor@example.info
Instead of using regex you can use PHP's built in filter_var()
with the FILTER_VALIDATE_EMAIL
filter applied. It'll return true(y)/false if it's a valid email and you don't have to mess around with some very complex regex.
You use it like:
$email_a = 'joe@example.com';
$email_b = 'bogus';
if (filter_var($email_a, FILTER_VALIDATE_EMAIL)) { //returns true
echo "This (email_a) email address is considered valid.";
}
if (filter_var($email_b, FILTER_VALIDATE_EMAIL)) { //returns false
echo "This (email_b) email address is considered valid.";
}
From the PHP's Validation, and filter_var pages.
精彩评论