После поиска хорошей процедуры проверки электронной почты, я нашел этот ответ на похожий вопрос и решил, что это выглядит как наиболее вероятный кандидат.Я реализовал следующий класс для проверки электронной почты (класс 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) | (?"ed_string))
(?<domain> (?&dot_atom) | (?&domain_literal))
(?<domain_literal> (?&CFWS)? \[ (?: (?&FWS)? (?&dcontent))* (?&FWS)?
\] (?&CFWS)?)
(?<dcontent> (?&dtext) | (?"ed_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) | (?"ed_pair))
(?<quoted_string> (?&CFWS)? (?&DQUOTE) (?:(?&FWS)? (?&qcontent))*
(?&FWS)? (?&DQUOTE) (?&CFWS)?)
(?<word> (?&atom) | (?"ed_string))
(?<phrase> (?&word)+)
# Folding white space
(?<FWS> (?: (?&WSP)* (?&CRLF))? (?&WSP)+)
(?<ctext> (?&NO_WS_CTL) | [\x21-\x27\x2a-\x5b\x5d-\x7e])
(?<ccontent> (?&ctext) | (?"ed_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$
, но это регулярное выражение является более продвинутым, чем большинство из тех, с которыми я работал в прошлом, и я не уверен, куда должны идти ^ и $.Если бы вы могли помочь с этим, я был бы признателен.