Регулярное выражение веселья с электронными письмами;домен верхнего уровня не требуется, когда он должен быть - PullRequest
0 голосов
/ 13 октября 2009

Я пытаюсь создать регулярные выражения, которые будут фильтровать действительные электронные письма, используя PHP, и столкнулись с проблемой, которая противоречит тому, что я понимаю о регулярных выражениях. Вот код, который я использую.

if (!preg_match('/^[-a-zA-Z0-9_.]+@[-a-zA-Z0-9]+.[a-zA-Z]{2,4}$/', $string)) {
return $false;
}

Теперь из материалов, которые я исследовал, это должно позволять содержанию до @ быть несколькими буквами, цифрами, символами подчеркивания и точками, затем впоследствии разрешать несколько букв и цифр, затем требовать точку, затем две-четыре буквы для домена верхнего уровня.

Однако сейчас он игнорирует требование наличия домена верхнего уровня. Например, a@b.c, очевидно, является действительным (и должно быть), но a @ b также возвращается как действительное, что я хочу, чтобы ti был помечен как не очень.

Я уверен, что что-то упустил, но после часа просмотра Google я не понимаю, что это может быть. У кого-нибудь есть ответ на эту загадку?

РЕДАКТИРОВАТЬ: скорость, с которой приходят ответы, делает этот сайт лучше, чем его конкуренты. Молодец!

Ответы [ 6 ]

5 голосов
/ 13 октября 2009

Вы должны сбежать ., когда он не является частью группы: '/^[-a-zA-Z0-9_.]+@[-a-zA-Z0-9]+\.[a-zA-Z]{2,4}$/' В противном случае оно будет равно любой букве:

  • . - любой символ (но не символ новой строки \n, если не используется s модификатор )
  • \. - символ точки
  • [.] - символ точки (внутри группы символов)
5 голосов
/ 13 октября 2009

Вместо того, чтобы катиться самостоятельно, возможно, вам следует прочитать статью Как найти или проверить адрес электронной почты на Regular-Expressions.info . В статье также обсуждаются причины, по которым вам может не понадобиться проверять адрес электронной почты с помощью регулярных выражений, и приводятся 3 регулярных выражения, которые вы могли бы рассмотреть вместо собственных.

3 голосов
/ 13 октября 2009

Со страницы Сравнение адресов электронной почты для проверки правильности регулярных выражений : Герт Де Деккер из проекта Kohana разработал почти идеальный вариант:

/^[-_a-z0-9\'+*$^&%=~!?{}]++(?:\.[-_a-z0-9\'+*$^&%=~!?{}]+)*+@(?:(?![-.])[-a-z0-9.]+(?<![-.])\.[a-z]{2,6}|\d{1,3}(?:\.\d{1,3}){3})(?::\d++)?$/iD

Но в PHP есть и встроенная функция filter_var($email, FILTER_VALIDATE_EMAIL), но она, похоже, находится в стадии разработки. И есть другое серьезное решение: PEAR: Подтвердить . Я думаю, что решение PEAR является лучшим.

2 голосов
1 голос
/ 13 октября 2009

Это наиболее разумный компромисс между спецификацией и реальной жизнью, который я видел:

[a-z0-9!#$%&'*+/=?^_`{|}~-]+
(?:\.[a-z0-9!#$%&'*+/=?^_`{|}~-]+)*
@
(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+
(?:[A-Z]{2}|com|org|net|gov|mil|biz|info|mobi|name|aero|jobs|museum)\b

Конечно, вы должны удалить разрывы строк и обновить их, если станет доступно больше доменов верхнего уровня.

0 голосов
/ 13 октября 2009

Одна точка в регулярном выражении означает «совпадение любой символ». И это именно то, что происходит, когда отсутствует домен верхнего уровня (также, конечно, когда он присутствует).

Таким образом, вы должны изменить свой код следующим образом:

if (!preg_match('/^[-a-zA-Z0-9_.]+@[-a-zA-Z0-9]+\.[a-zA-Z]{2,4}$/', $string)) {
    return $false;
}

И, кстати: в локальной части допускается намного больше символов, чем позволяет ваше регулярное выражение в настоящее время.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...