Как проверить адрес электронной почты с помощью регулярного выражения? - PullRequest
3109 голосов
/ 14 октября 2008

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

Я использую его в нескольких программах PHP, и он работает большую часть времени. Однако время от времени со мной связывается кто-то, у кого проблемы с сайтом, который его использует, и мне приходится вносить некоторые коррективы (совсем недавно я понял, что не разрешаю 4-символьные TLD).

Какое лучшее регулярное выражение вы видели или видели для проверки писем?

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

Ответы [ 72 ]

3 голосов
/ 16 декабря 2009

Никто не упомянул проблему локализации (i18), что если у вас есть клиенты со всего мира? Затем вам нужно будет подразделить ваше регулярное выражение на страну / регион, что, как я видел, разработчики в итоге создали большой словарь / конфигурацию. Хорошей отправной точкой может стать настройка языка браузера пользователя.

3 голосов
/ 13 июля 2018

Согласно RFC 2821 и RFC 2822 , локальная часть адресов электронной почты может использовать любой из следующих символов ASCII:

  1. Прописные и строчные буквы
  2. Цифры от 0 до 9
  3. Символы,! # $% & '* + - / =? ^ _ `{|} ~
  4. Персонаж "." при условии, что это не первый или последний символ в локальной части.

Совпадения:

  • a&d@somedomain.com
  • a*d@somedomain.com
  • a/d@somedomain.com

Non-Похожее:

  • .abc@somedomain.com
  • а. @ Somedomain.com
  • а> b@somedomain.com

Для того, что соответствует RFC 2821, 2822, вы можете использовать:

^((([!#$%&'*+\-/=?^_`{|}~\w])|([!#$%&'*+\-/=?^_`{|}~\w][!#$%&'*+\-/=?^_`{|}~\.\w]{0,}[!#$%&'*+\-/=?^_`{|}~\w]))[@]\w+([-.]\w+)*\.\w+([-.]\w+)*)$

Электронная почта - соответствует RFC 2821, 2822

3 голосов
/ 19 сентября 2015

Я нашел замечательную статью , в которой говорится, что лучший способ проверить адрес электронной почты - это выражение regex /.+@.+\..+/i

3 голосов
/ 06 августа 2014

Регулярные выражения, опубликованные в этой теме, устарели из-за появления новых общих доменов верхнего уровня (рДВУ) (например, .london, .basketball,. 通 販). Для подтверждения адреса электронной почты есть два ответа (это было бы актуально для подавляющего большинства).

  1. Как говорится в основном ответе - не используйте регулярное выражение, просто подтвердите его, отправив электронное письмо на адрес (Catch exclude for invalid address)
  2. Используйте очень общее регулярное выражение, чтобы хотя бы убедиться, что они используют структуру электронной почты {something}@{something}.{something}. Нет смысла переходить к подробному регулярному выражению, потому что вы не поймаете их всех, и через несколько лет будет новая партия, и вам придется снова обновлять регулярное выражение.

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

(.+)@(.+){2,}\.(.+){2,}
2 голосов
/ 25 августа 2014

Java Mail API делает магию для нас. try { InternetAddress internetAddress = new InternetAddress(email); internetAddress.validate(); return true; } catch(Exception ex) { return false; } Я получил это от здесь

2 голосов
/ 19 июля 2014

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

  • Если ваше приложение имеет что-то очень техническое по своей природе (или что-то внутреннее для организаций), то, возможно, вам нужно поддерживать IP-адреса вместо доменных имен или комментарии в «локальной» части адреса электронной почты.
  • Если ваше приложение многонациональное, я бы подумал о поддержке Unicode / UTF8.

Ведущий ответ на ваш вопрос в настоящее время ссылается на «полностью регулярное выражение, соответствующее RFC ‑ 822». Однако, несмотря на сложность этого регулярного выражения и его предполагаемого внимания к деталям в правилах RFC, он полностью терпит неудачу, когда речь заходит о поддержке Unicode.

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

/^(?!\.)((?!.*\.{2})[a-zA-Z0-9\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u0250-\u02AF\u0300-\u036F\u0370-\u03FF\u0400-\u04FF\u0500-\u052F\u0530-\u058F\u0590-\u05FF\u0600-\u06FF\u0700-\u074F\u0750-\u077F\u0780-\u07BF\u07C0-\u07FF\u0900-\u097F\u0980-\u09FF\u0A00-\u0A7F\u0A80-\u0AFF\u0B00-\u0B7F\u0B80-\u0BFF\u0C00-\u0C7F\u0C80-\u0CFF\u0D00-\u0D7F\u0D80-\u0DFF\u0E00-\u0E7F\u0E80-\u0EFF\u0F00-\u0FFF\u1000-\u109F\u10A0-\u10FF\u1100-\u11FF\u1200-\u137F\u1380-\u139F\u13A0-\u13FF\u1400-\u167F\u1680-\u169F\u16A0-\u16FF\u1700-\u171F\u1720-\u173F\u1740-\u175F\u1760-\u177F\u1780-\u17FF\u1800-\u18AF\u1900-\u194F\u1950-\u197F\u1980-\u19DF\u19E0-\u19FF\u1A00-\u1A1F\u1B00-\u1B7F\u1D00-\u1D7F\u1D80-\u1DBF\u1DC0-\u1DFF\u1E00-\u1EFF\u1F00-\u1FFFu20D0-\u20FF\u2100-\u214F\u2C00-\u2C5F\u2C60-\u2C7F\u2C80-\u2CFF\u2D00-\u2D2F\u2D30-\u2D7F\u2D80-\u2DDF\u2F00-\u2FDF\u2FF0-\u2FFF\u3040-\u309F\u30A0-\u30FF\u3100-\u312F\u3130-\u318F\u3190-\u319F\u31C0-\u31EF\u31F0-\u31FF\u3200-\u32FF\u3300-\u33FF\u3400-\u4DBF\u4DC0-\u4DFF\u4E00-\u9FFF\uA000-\uA48F\uA490-\uA4CF\uA700-\uA71F\uA800-\uA82F\uA840-\uA87F\uAC00-\uD7AF\uF900-\uFAFF\.!#$%&'*+-/=?^_`{|}~\-\d]+)@(?!\.)([a-zA-Z0-9\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u0250-\u02AF\u0300-\u036F\u0370-\u03FF\u0400-\u04FF\u0500-\u052F\u0530-\u058F\u0590-\u05FF\u0600-\u06FF\u0700-\u074F\u0750-\u077F\u0780-\u07BF\u07C0-\u07FF\u0900-\u097F\u0980-\u09FF\u0A00-\u0A7F\u0A80-\u0AFF\u0B00-\u0B7F\u0B80-\u0BFF\u0C00-\u0C7F\u0C80-\u0CFF\u0D00-\u0D7F\u0D80-\u0DFF\u0E00-\u0E7F\u0E80-\u0EFF\u0F00-\u0FFF\u1000-\u109F\u10A0-\u10FF\u1100-\u11FF\u1200-\u137F\u1380-\u139F\u13A0-\u13FF\u1400-\u167F\u1680-\u169F\u16A0-\u16FF\u1700-\u171F\u1720-\u173F\u1740-\u175F\u1760-\u177F\u1780-\u17FF\u1800-\u18AF\u1900-\u194F\u1950-\u197F\u1980-\u19DF\u19E0-\u19FF\u1A00-\u1A1F\u1B00-\u1B7F\u1D00-\u1D7F\u1D80-\u1DBF\u1DC0-\u1DFF\u1E00-\u1EFF\u1F00-\u1FFF\u20D0-\u20FF\u2100-\u214F\u2C00-\u2C5F\u2C60-\u2C7F\u2C80-\u2CFF\u2D00-\u2D2F\u2D30-\u2D7F\u2D80-\u2DDF\u2F00-\u2FDF\u2FF0-\u2FFF\u3040-\u309F\u30A0-\u30FF\u3100-\u312F\u3130-\u318F\u3190-\u319F\u31C0-\u31EF\u31F0-\u31FF\u3200-\u32FF\u3300-\u33FF\u3400-\u4DBF\u4DC0-\u4DFF\u4E00-\u9FFF\uA000-\uA48F\uA490-\uA4CF\uA700-\uA71F\uA800-\uA82F\uA840-\uA87F\uAC00-\uD7AF\uF900-\uFAFF\-\.\d]+)((\.([a-zA-Z\u0080-\u00FF\u0100-\u017F\u0180-\u024F\u0250-\u02AF\u0300-\u036F\u0370-\u03FF\u0400-\u04FF\u0500-\u052F\u0530-\u058F\u0590-\u05FF\u0600-\u06FF\u0700-\u074F\u0750-\u077F\u0780-\u07BF\u07C0-\u07FF\u0900-\u097F\u0980-\u09FF\u0A00-\u0A7F\u0A80-\u0AFF\u0B00-\u0B7F\u0B80-\u0BFF\u0C00-\u0C7F\u0C80-\u0CFF\u0D00-\u0D7F\u0D80-\u0DFF\u0E00-\u0E7F\u0E80-\u0EFF\u0F00-\u0FFF\u1000-\u109F\u10A0-\u10FF\u1100-\u11FF\u1200-\u137F\u1380-\u139F\u13A0-\u13FF\u1400-\u167F\u1680-\u169F\u16A0-\u16FF\u1700-\u171F\u1720-\u173F\u1740-\u175F\u1760-\u177F\u1780-\u17FF\u1800-\u18AF\u1900-\u194F\u1950-\u197F\u1980-\u19DF\u19E0-\u19FF\u1A00-\u1A1F\u1B00-\u1B7F\u1D00-\u1D7F\u1D80-\u1DBF\u1DC0-\u1DFF\u1E00-\u1EFF\u1F00-\u1FFF\u20D0-\u20FF\u2100-\u214F\u2C00-\u2C5F\u2C60-\u2C7F\u2C80-\u2CFF\u2D00-\u2D2F\u2D30-\u2D7F\u2D80-\u2DDF\u2F00-\u2FDF\u2FF0-\u2FFF\u3040-\u309F\u30A0-\u30FF\u3100-\u312F\u3130-\u318F\u3190-\u319F\u31C0-\u31EF\u31F0-\u31FF\u3200-\u32FF\u3300-\u33FF\u3400-\u4DBF\u4DC0-\u4DFF\u4E00-\u9FFF\uA000-\uA48F\uA490-\uA4CF\uA700-\uA71F\uA800-\uA82F\uA840-\uA87F\uAC00-\uD7AF\uF900-\uFAFF]){2,63})+)$/i

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

Существует также живая демонстрация для регулярного выражения по адресу: http://jsfiddle.net/aossikine/qCLVH/3/

1 голос
/ 11 мая 2013

Самая популярная в мире платформа для ведения блогов WordPress использует эту функцию для проверки адреса электронной почты ..

Но они делают это в несколько этапов.

Вам больше не нужно беспокоиться при использовании регулярного выражения, упомянутого в этой функции.

Вот функция ..

/**
 * Verifies that an email is valid.
 *
 * Does not grok i18n domains. Not RFC compliant.
 *
 * @since 0.71
 *
 * @param string $email Email address to verify.
 * @param boolean $deprecated Deprecated.
 * @return string|bool Either false or the valid email address.
 */
function is_email( $email, $deprecated = false ) {
    if ( ! empty( $deprecated ) )
        _deprecated_argument( __FUNCTION__, '3.0' );

    // Test for the minimum length the email can be
    if ( strlen( $email ) < 3 ) {
        return apply_filters( 'is_email', false, $email, 'email_too_short' );
    }

    // Test for an @ character after the first position
    if ( strpos( $email, '@', 1 ) === false ) {
        return apply_filters( 'is_email', false, $email, 'email_no_at' );
    }

    // Split out the local and domain parts
    list( $local, $domain ) = explode( '@', $email, 2 );

    // LOCAL PART
    // Test for invalid characters
    if ( !preg_match( '/^[a-zA-Z0-9!#$%&\'*+\/=?^_`{|}~\.-]+$/', $local ) ) {
        return apply_filters( 'is_email', false, $email, 'local_invalid_chars' );
    }

    // DOMAIN PART
    // Test for sequences of periods
    if ( preg_match( '/\.{2,}/', $domain ) ) {
        return apply_filters( 'is_email', false, $email, 'domain_period_sequence' );
    }

    // Test for leading and trailing periods and whitespace
    if ( trim( $domain, " \t\n\r\0\x0B." ) !== $domain ) {
        return apply_filters( 'is_email', false, $email, 'domain_period_limits' );
    }

    // Split the domain into subs
    $subs = explode( '.', $domain );

    // Assume the domain will have at least two subs
    if ( 2 > count( $subs ) ) {
        return apply_filters( 'is_email', false, $email, 'domain_no_periods' );
    }

    // Loop through each sub
    foreach ( $subs as $sub ) {
        // Test for leading and trailing hyphens and whitespace
        if ( trim( $sub, " \t\n\r\0\x0B-" ) !== $sub ) {
            return apply_filters( 'is_email', false, $email, 'sub_hyphen_limits' );
        }

        // Test for invalid characters
        if ( !preg_match('/^[a-z0-9-]+$/i', $sub ) ) {
            return apply_filters( 'is_email', false, $email, 'sub_invalid_chars' );
        }
    }

    // Congratulations your email made it!
    return apply_filters( 'is_email', $email, $email, null );
}
1 голос
/ 07 июня 2014

Регулярное выражение, которое делает то, что, как говорят стандарты, разрешено, в соответствии с тем, что я видел о них, это:

/^(?!(^[.-].*|.*[.-]@|.*\.{2,}.*)|^.{254}.+@)([a-z\xC0-\xFF0-9!#$%&'*+\/=?^_`{|}~.-]+@)(?!.{253}.+$)((?!-.*|.*-\.)([a-z0-9-]{1,63}\.)+[a-z]{2,63}|(([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])\.){3}([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9]))$/gim

Демо / Анализ отладки ( интерактивный )

Разделить:

^(?!(^[.-].*|.*[.-]@|.*\.{2,}.*)|^.{254}.+@)
([a-z\xC0-\xFF0-9!#$%&'*+\/=?^_`{|}~.-]+@)
(?!.{253}.+$)
(
    (?!-.*|.*-\.)
    ([a-z0-9-]{1,63}\.)+
    [a-z]{2,63}
    |
    (([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])\.){3}
    ([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])
)$

Анализ:

(?!(^[.-].*|.*[.-]@|.*\.{2,}.*)|^.{254}.+@)

Отрицательный прогноз для адреса, начинающегося с ., заканчивающегося одним, имеющего .. в нем или превышающего максимальную длину в 254 символа


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

соответствует 1 или более из разрешенных символов , к нему применяется отрицательный взгляд


(?!.{253}.+$)

Отрицательный взгляд на часть имени домена, ограничивающая его до всего 253 символов


(?!-.*|.*-\.)

Отрицательный прогноз для каждого из доменных имен, которые не допускаются , начиная или заканчивая .


([a-z0-9-]{1,63}\.)+

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


[a-zA-Z]{2,63}

простое совпадение групп для разрешенного домена верхнего уровня, который в настоящее время все еще ограничен только буквами, но действительно включает> 4-буквенные TLD .


(([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])\.){3}
([01]?[0-9]{2}|2([0-4][0-9]|5[0-5])|[0-9])

альтернатива для доменных имен: это соответствует первым 3 числам в IP-адресе с a . позади него, а затем четвертому числу в IP-адресе без . позади него.

1 голос
/ 07 ноября 2014

Ниже приведено регулярное выражение для проверки адреса электронной почты

^.+@\w+(\.\w+)+$
1 голос
/ 11 сентября 2014

Как уже упоминалось, вы не можете проверить электронную почту с помощью регулярного выражения. Тем не менее, вот что мы в настоящее время используем, чтобы убедиться, что ввод пользователя не является полностью фиктивным (забывая TLD и т. Д.).

Это регулярное выражение разрешает домены IDN и специальные символы (например, Umlauts) до и после знака @.

/^[\w.+-_]+@[^.][\w.-]*\.[\w-]{2,63}$/iu
...