找到好的電子郵件驗證程序後,我發現this answer to a similar question,並認定它看起來最有可能成爲候選人。我實現爲電子郵件驗證以下類(它繼承的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, https://stackoverflow.com/questions/201323/what-is-the-best-regular-expression-for-validating-email-addresses/1917982#1917982
*/
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"[email protected]
(通行證,應該是無效的)[email protected]@[email protected]
(通過,應該是無效的)this\ is\"really\"not\\[email protected]
(通行證,應該是無效的)
PHP似乎正確解析正則表達式,它不會發出任何錯誤,警告或通知。另外,我所有其他的測試用例(其他7個有效地址和另外2個無效的地址)都應該是合格或不合格的,所以我懷疑這是因爲我的PHP版本(5.3.8)不支持這裏使用的正則表達式語法。但由於我有誤報和誤報,顯然有些問題。要麼我的測試數據不正確(正如我所說,我大多是從維基百科剔除的),或者正則表達式在某種程度上是不正確的。
上面輸入的正則表達式正確嗎?如果不是,需要修正什麼?如果它是正確的,那麼我的測試用例是否有問題?
編輯:我也忘了提及,因爲這是一個驗證類,它只需要傳遞包含電子郵件地址的字符串而沒有別的。我不想在非電子郵件地址數據中傳遞包含有效電子郵件地址的字符串。我知道你通過使用^pattern_goes_here$
來做到這一點,但是這個正則表達式比我過去使用過的大多數更加先進,而且我不確定^和$應該在哪裏。如果你也可以提供幫助,我會很感激。
你不能使用:'filter_var('[email protected]',FILTER_VALIDATE_EMAIL)'? – 2011-12-17 21:55:48
請注意,由於規格非常大,因此很難製作正則表達式電子郵件驗證程序!我不認爲有一個匹配所有可能的情況的單一正則表達式。 – PeeHaa 2011-12-17 21:59:02
@GordonM:關於你編輯。就像通常那樣,將它放在分隔符後面和分隔符之前。 – PeeHaa 2011-12-17 22:03:45