Не удается получить подтверждение по электронной почте для работы - PullRequest
0 голосов
/ 18 декабря 2011

После поиска хорошей процедуры проверки электронной почты, я нашел этот ответ на похожий вопрос и решил, что это выглядит как наиболее вероятный кандидат.Я реализовал следующий класс для проверки электронной почты (класс RegexMatch, от которого он наследует, проверяет строку на соответствие регулярному выражению, как указано в ключе иглы массива ассоциативной конфигурации):

class Email extends RegexMatch implements iface\Prop
{
    const
        /**
         * Regular expression for validating email addresses
         * 
         * This regex is meant to validate against RFC 5322 and was taken from
         * a post on Stack Overflow regarding email validation (see the links)
         * 
         * @link http://www.ietf.org/rfc/rfc5322.txt, /159932/kak-proverit-adres-elektronnoi-pochty-s-pomoschy-regulyarnogo-vyrazheniya#160009
         */
         PATTERN    = '
/(?(DEFINE)
   (?<address>         (?&mailbox) | (?&group))
   (?<mailbox>         (?&name_addr) | (?&addr_spec))
   (?<name_addr>       (?&display_name)? (?&angle_addr))
   (?<angle_addr>      (?&CFWS)? < (?&addr_spec) > (?&CFWS)?)
   (?<group>           (?&display_name) : (?:(?&mailbox_list) | (?&CFWS))? ;
                                          (?&CFWS)?)
   (?<display_name>    (?&phrase))
   (?<mailbox_list>    (?&mailbox) (?: , (?&mailbox))*)

   (?<addr_spec>       (?&local_part) \@ (?&domain))
   (?<local_part>      (?&dot_atom) | (?&quoted_string))
   (?<domain>          (?&dot_atom) | (?&domain_literal))
   (?<domain_literal>  (?&CFWS)? \[ (?: (?&FWS)? (?&dcontent))* (?&FWS)?
                                 \] (?&CFWS)?)
   (?<dcontent>        (?&dtext) | (?&quoted_pair))
   (?<dtext>           (?&NO_WS_CTL) | [\x21-\x5a\x5e-\x7e])

   (?<atext>           (?&ALPHA) | (?&DIGIT) | [!#\$%&\'*+-\/=?^_`{|}~])
   (?<atom>            (?&CFWS)? (?&atext)+ (?&CFWS)?)
   (?<dot_atom>        (?&CFWS)? (?&dot_atom_text) (?&CFWS)?)
   (?<dot_atom_text>   (?&atext)+ (?: \. (?&atext)+)*)

   (?<text>            [\x01-\x09\x0b\x0c\x0e-\x7f])
   (?<quoted_pair>     \\ (?&text))

   (?<qtext>           (?&NO_WS_CTL) | [\x21\x23-\x5b\x5d-\x7e])
   (?<qcontent>        (?&qtext) | (?&quoted_pair))
   (?<quoted_string>   (?&CFWS)? (?&DQUOTE) (?:(?&FWS)? (?&qcontent))*
                        (?&FWS)? (?&DQUOTE) (?&CFWS)?)

   (?<word>            (?&atom) | (?&quoted_string))
   (?<phrase>          (?&word)+)

   # Folding white space
   (?<FWS>             (?: (?&WSP)* (?&CRLF))? (?&WSP)+)
   (?<ctext>           (?&NO_WS_CTL) | [\x21-\x27\x2a-\x5b\x5d-\x7e])
   (?<ccontent>        (?&ctext) | (?&quoted_pair) | (?&comment))
   (?<comment>         \( (?: (?&FWS)? (?&ccontent))* (?&FWS)? \) )
   (?<CFWS>            (?: (?&FWS)? (?&comment))*
                       (?: (?:(?&FWS)? (?&comment)) | (?&FWS)))

   # No whitespace control
   (?<NO_WS_CTL>       [\x01-\x08\x0b\x0c\x0e-\x1f\x7f])

   (?<ALPHA>           [A-Za-z])
   (?<DIGIT>           [0-9])
   (?<CRLF>            \x0d \x0a)
   (?<DQUOTE>          ")
   (?<WSP>             [\x20\x09])
 )

 (?&address)/x';

    public function setConfig (array $config = array ())
    {
        $config = array_merge ($config, array ('needle' => self::PATTERN));
        return (parent::setConfig ($config));
    }

    public function isValid ()
    {
        return ((is_null ($this -> getData ()))
            || (parent::isValid ()));
    }
}

Я также построилТест PHPUnit, который запускает этот класс для различных перестановок действительных и недействительных адресов электронной почты, собранных из различных источников (в основном из Википедии).

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

  • much."more\ unusual"@example.com (Сбой, должен быть действительным)
  • "(),:;<>[\]@example.com (Передачи, должен быть недействительным)
  • just"not"right@example.com (пропуски должны быть недействительными)
  • A@b@c@example.com (пропуски должны быть недействительными)
  • this\ is\"really\"not\\allowed@example.com (пропуски должны быть недействительными)

PHP, кажется, правильно анализирует регулярное выражение, он не выдает никаких ошибок, предупреждений или уведомлений.Кроме того, все мои другие тестовые примеры (7 других действительных адресов и 2 других недействительных) пройдены или не пройдены, как и должно быть, поэтому я сомневаюсь, что это потому, что моя версия PHP (5.3.8) не поддерживает синтаксис регулярного выражения, используемый здесь,Но так как у меня есть и ложные срабатывания, и ложные отрицания, очевидно, что-то не так.Либо мои тестовые данные неверны (что, как я уже сказал, я в основном отбирал из Википедии), либо регулярное выражение как есть неверно в некотором смысле

Правильно ли введенное выше регулярное выражение?Если нет, какие исправления необходимо внести?Если это правильно, то что-то не так с моими тестами?

РЕДАКТИРОВАТЬ : Я также забыл упомянуть, поскольку это класс проверки, он должен передавать только строки, содержащие адрес электронной почты и ничего больше.Я не хочу передавать строки, содержащие действительный адрес электронной почты, в данных, не относящихся к адресу электронной почты.Я знаю, что вы делаете это с помощью ^pattern_goes_here$, но это регулярное выражение является более продвинутым, чем большинство из тех, с которыми я работал в прошлом, и я не уверен, куда должны идти ^ и $.Если бы вы могли помочь с этим, я был бы признателен.

Ответы [ 2 ]

2 голосов
/ 18 декабря 2011

Полная проверка адресов электронной почты - это очень хитрый бизнес.

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

http://fightingforalostcause.net/misc/2006/compare-email-regex.php

Выражение с лучшим счетом в настоящее время используется в PHP filter_var (), основанном на регулярном выражении Майкла Руштона

Я настоятельно рекомендую вам использовать filter_var()

1 голос
/ 18 декабря 2011

Если вы хотите добавить ^ и $ якоря, это будет место:

  ^(?&address)$  /x';

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

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