【发布时间】:2019-05-02 22:49:41
【问题描述】:
我正在尝试创建一个(几乎)与 RFC5321 和 5322 完全兼容的 PHP PCRE 正则表达式来测试 email addresses。我唯一不需要的是(评论)部分。我在这里看到了一些其他的尝试,但是当我对它们进行测试时,它们并不都有效。
我一直在研究一个非常接近的:
^(([\w \!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~\.]{1,64})|("[\w \!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~\.]{1,64}"))@(([\w\-]*\.?[\w\-]*)|(\[\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}\])|(\[IPv6:[\da-fA-F]{0,4}:[\da-fA-F]{0,4}:[\da-fA-F]{0,4}:[\da-fA-F]{0,4}\]))$
分解:
本地部分:
(
最多匹配 64 个允许的字符
([\w \!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~\.]{1,64})
|
或匹配带引号的字符串中的同一组字符:
("[\w \!\#\$\%\&\'\*\+\-\/\=\?\^\`\{\|\}\~\.]{1,64}")
)
结束本地部分。
匹配@符号
@
匹配域部分:
(
使用允许的字符匹配域部分:
([\w\-]*\.?[\w\-]*)
或 ipv4(它不会检查以确保它们是
(\[\d{1,3}.\d{1,3}.\d{1,3}.\d{1,3}\])
或ipv6
(\[IPv6:[\da-fA-F]{0,4}:[\da-fA-F]{0,4}:[\da-fA-F]{0,4}:[\da-fA-F]{0,4}\])
)
它唯一缺少的是能够检查多个连续的 . (句点)在引用的本地部分之外。我使用我自己的一些测试和wikipedia article about email addresses 上的测试对regex101.com 与以下所有地址进行了测试:
bob@smith.com
bob.smith@smith.com
bob-smith@smith.com
bob-smith@bob-smith.com
b0b!-...smith@smith.com <-DOES NOT VALIDATE CORRECTLY - MULTIPLE .'s
bob&smith@smith.com
"bob..smith"@smith.com
simple@example.com
very.common@example.com
disposable.style.email.with+symbol@example.com
other.email-with-hyphen@example.com
fully-qualified-domain@example.com
user.name+tag+sorting@example.com
x@example.com
example-indeed@strange-example.com
admin@mailserver1
example@s.example
" "@example.org
"john..doe"@example.org
Abc.example.com
A@b@c@example.com
a"b(c)d,e:f;g<h>i[j\k]l@example.com
just"not"right@example.com
this is"not\allowed@example.com
this\ still\"not\\allowed@example.com
1234567890123456789012345678901234567890123456789012345678901234+x@example.com
john..doe@example.com <-DOES NOT VALIDATE CORRECTLY - MULTIPLE .'s
john.doe@example..com
我尝试使用前瞻和后瞻断言来测试连续的周期,但我无法弄清楚。我认为这是它唯一缺少的东西(除了 cmets,出于我的目的,这不是必需的)。
有没有办法检查不会改变我目前拥有太多东西的时期,还是需要不同的方法?
如果我错过了任何其他内容,请告诉我。
谢谢。
【问题讨论】:
-
尝试在
^之后添加(?!("[^"]*"|[^"])*\.{2})。如果您在 regex101 进行测试,请使用(?!("[^"\n]*"|[^"\n])*\.{2}) -
那太好了,谢谢!