Есть ли хороший способ проверить ввод формы с помощью регулярного выражения, чтобы убедиться, что это адрес электронной почты правильного стиля? Искал с прошлой ночи, и у всех, кто отвечал на вопросы людей по этой теме, тоже, похоже, есть проблемы с этим, если это адрес электронной почты поддомена.
Как проверить действующий адрес электронной почты?
Ответы (18)
Бессысленно. Даже если вы можете убедиться, что адрес электронной почты синтаксически действителен, вам все равно необходимо убедиться, что он не был введен с ошибкой и что он действительно переходит к тому человеку, который, по вашему мнению, это делает. Единственный способ сделать это - отправить им электронное письмо и попросить их щелкнуть ссылку для подтверждения.
Поэтому обычно достаточно самой простой проверки (например, что они случайно не ввели свой почтовый адрес). Что-то вроде: у него ровно один знак @
и хотя бы один .
в части после @
:
[^@]+@[^@]+\.[^@]+
Вы, вероятно, также захотите запретить пробелы - вероятно, есть действительные адреса электронной почты с пробелами в них, но я никогда их не видел, поэтому шансы на то, что это ошибка пользователя, на вашей стороне.
Если вам нужна полная проверка, просмотрите этот вопрос < / а>.
Обновление: вот как вы можете использовать любое такое регулярное выражение:
import re
if not re.match(r"... regex here ...", email):
# whatever
Python ≥3.4 имеет re.fullmatch
, который предпочтительнее re.match
.
Обратите внимание на r
перед строкой; таким образом, вам не нужно будет дважды убегать.
Если вам нужно проверить большое количество регулярных выражений, возможно, будет быстрее сначала скомпилировать регулярное выражение:
import re
EMAIL_REGEX = re.compile(r"... regex here ...")
if not EMAIL_REGEX.match(email):
# whatever
Другой вариант - использовать пакет validate_email
, который фактически связывается с сервер SMTP, чтобы убедиться, что адрес существует. Однако это еще не гарантирует, что он принадлежит правильному человеку.
if not re.match("[^@]+@[^@]+\.[^@]+", email):
?
- person Bobby; 05.11.2011
if not re.match(r"^[A-Za-z0-9\.\+_-]+@[A-Za-z0-9\._-]+\.[a-zA-Z]*$", email):
, поскольку это кажется наиболее правдоподобным сценарием, после которого на указанный адрес было отправлено письмо с подтверждением.
- person Bobby; 05.11.2011
/
, видимым в адресах университета). Еще один целый класс, который вы полностью блокируете, - это интернационализированные доменные имена. На самом деле, нет веских причин блокировать действующие адреса электронной почты. Я с неохотой прощаю людей, которые не разрешают адреса электронной почты, такие как 100%." foo b@r"(this is a cool email address!)@(just a tld)com(ok)
, но я думаю, что проверка на символ @
- это все, что вам нужно (домен верхнего уровня действителен как часть домена, но это маловероятно).
- person Chris Morgan; 06.03.2013
EMAIL_REGEX = re.compile(r"[^@\s]+@[^@\s]+\.[^@\s.]+$")
- person gaefan; 18.08.2015
re.compile(r"[^@\s]+@[^@\s]+\.[a-zA-Z0-9]+$")
- person gaefan; 29.08.2015
"@"@localhost
и \@@localhost
действительны.
- person Julien Palard; 03.10.2016
r'[\w!#$%&\'*+-/=?^_`{|}~.]+@[\w\.-]+'
- person sponrad; 11.04.2018
fullmatch
, в моем случае для писем типа [email protected] он совпадает, но не полностью совпадает. Фактически совпадение равно [email protected]
, поэтому om
опускается.
- person milosmns; 28.07.2019
@
. Если это произойдет, скорее всего, это будет ошибка пользователя (например, пользователь дважды случайно нажал Ctrl + V), чем чей-то реальный адрес электронной почты.
- person Thomas; 18.11.2020
Стандартная библиотека Python имеет функцию синтаксического анализа электронной почты: email.utils.parseaddr()
.
Он возвращает кортеж из двух частей, содержащий настоящее имя и фактический адрес электронной почты:
>>> from email.utils import parseaddr
>>> parseaddr('[email protected]')
('', '[email protected]')
>>> parseaddr('Full Name <[email protected]>')
('Full Name', '[email protected]')
>>> parseaddr('"Full Name with quotes and <[email protected]>" <[email protected]>')
('Full Name with quotes and <[email protected]>', '[email protected]')
И если синтаксический анализ завершился неудачно, он возвращает два кортежа пустых строк:
>>> parseaddr('[invalid!email]')
('', '')
Проблема с этим парсером заключается в том, что он принимает все, что считается допустимым адресом электронной почты для RFC-822 и его друзей, включая многие вещи, которые явно не могут быть адресованы в широком Интернете:
>>> parseaddr('invalid@example,com') # notice the comma
('', 'invalid@example')
>>> parseaddr('invalid-email')
('', 'invalid-email')
Итак, как выразился @TokenMacGuy, единственный окончательный способ проверить адрес электронной почты - это отправить электронное письмо на ожидаемый адрес и дождаться, пока пользователь отреагирует на информацию внутри сообщения.
Однако вы можете проверить хотя бы наличие знака @ на втором элементе кортежа, как предлагает @bvukelic:
>>> '@' in parseaddr("invalid-email")[1]
False
Если вы хотите пойти дальше, вы можете установить проект dnspython и разрешить почтовые серверы для домен электронной почты (часть после '@'), пытается отправить электронное письмо только при наличии реальных MX
серверов:
>>> from dns.resolver import query
>>> domain = 'foo@[email protected]'.rsplit('@', 1)[-1]
>>> bool(query(domain, 'MX'))
True
>>> query('example.com', 'MX')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
[...]
dns.resolver.NoAnswer
>>> query('not-a-domain', 'MX')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
[...]
dns.resolver.NXDOMAIN
Вы можете поймать как NoAnswer
, так и NXDOMAIN
, поймав dns.exception.DNSException
.
И да, foo@[email protected]
- это синтаксически правильный адрес. Только последний @
следует рассматривать для определения того, где начинается доменная часть.
@
после использования этой функции.
- person ; 26.06.2014
parseaddr(u"evil@addr")
сломает это.
- person Yajo; 23.10.2015
evil@addr
является таким же действительным адресом электронной почты, как и [email protected]
, и parseaddr()
рассматривает его как таковой. В конце концов, вам всегда нужно будет попробовать отправить электронное письмо на указанный адрес для проверки.
- person LeoRochael; 25.10.2015
email.utils.parseaddr('user@@host')
возвращает ('', 'user@')
- person skoval00; 15.02.2017
('', 'user@@host')
.
- person LeoRochael; 16.02.2017
Я не видел ответа здесь среди беспорядка пользовательских ответов Regex, но ...
Существует библиотека Python под названием py3-validate-email < s> validate_email, который имеет 3 уровня проверки электронной почты, включая запрос действительного SMTP-сервера. если адрес электронной почты действительный (без отправки электронного письма).
Установить
python -m pip install py3-validate-email
Основное использование:
from validate_email import validate_email
is_valid = validate_email(email_address='[email protected]', \
check_regex=True, check_mx=True, \
from_address='[email protected]', helo_host='my.host.name', \
smtp_timeout=10, dns_timeout=10, use_blacklist=True)
Для тех, кто интересуется грязными деталями, validate_email.py (источник) предназначен соблюдать RFC 2822.
Все, что мы на самом деле делаем, - это сравниваем входную строку с одним гигантским регулярным выражением. Но создание этого регулярного выражения и обеспечение его правильности намного проще, если собрать его из токенов, определенных RFC. Каждый из этих токенов тестируется в прилагаемом файле модульного теста.
вам может понадобиться модуль pyDNS для проверки серверов SMTP.
pip install pyDNS
или из Ubuntu
apt-get install python3-dns
sudo apt-get python3-dns
, похоже, работает на Ubuntu вместо sudo -H pip3 install pyDNS
, просто для записи.
- person Brōtsyorfuzthrāx; 02.09.2018
email@examplecom
. См. Большой список известных проблем.
- person Acumenus; 14.03.2019
Адреса электронной почты не так просты, как кажутся! Например, Bob_O'[email protected] - действительный адрес электронной почты.
Мне повезло с пакетом lepl (http://www.acooke.org/lepl/). Он может проверять адреса электронной почты, указанные в RFC 3696: http://www.faqs.org/rfcs/rfc3696.html а>
Нашел какой-то старый код:
import lepl.apps.rfc3696
email_validator = lepl.apps.rfc3696.Email()
if not email_validator("[email protected]"):
print "Invalid email"
lepl
был снят с производства.
- person ; 22.01.2013
Я нашел отличный (и проверенный) способ проверить действующий адрес электронной почты. Я вставляю сюда свой код:
# here i import the module that implements regular expressions
import re
# here is my function to check for valid email address
def test_email(your_pattern):
pattern = re.compile(your_pattern)
# here is an example list of email to check it at the end
emails = ["[email protected]", "[email protected]", "wha.t.`1an?ug{}[email protected]"]
for email in emails:
if not re.match(pattern, email):
print "You failed to match %s" % (email)
elif not your_pattern:
print "Forgot to enter a pattern!"
else:
print "Pass"
# my pattern that is passed as argument in my function is here!
pattern = r"\"?([-a-zA-Z0-9.`?{}]+@\w+\.\w+)\"?"
# here i test my function passing my pattern
test_email(pattern)
Я вижу здесь много сложных ответов. Некоторые из них не знают простой, истинный адрес электронной почты или имеют ложные срабатывания. Ниже приведен простейший способ проверить, является ли строка действительным адресом электронной почты. Он проверяет двух- и трехбуквенные TLD. Теперь, когда вы технически можете иметь более крупные, вы можете увеличить их с 3 до 4, 5 или даже 10.
import re
def valid_email(email):
return bool(re.search(r"^[\w\.\+\-]+\@[\w]+\.[a-z]{2,3}$", email))
re.match
лучше, чем bool(re.search)
- person Gahan; 19.06.2017
.co.uk
.
- person Peter; 01.10.2017
[email protected]
(потому что в части имени домена есть 2 точки)?
- person Mobigital; 25.12.2018
Обычно это решается с помощью регулярного выражения. Однако существует множество вариантов решений. В зависимости от того, насколько строгими вы должны быть, и если у вас есть индивидуальные требования для проверки, или вы примете любой действующий адрес электронной почты.
См. Эту страницу для справки: http://www.regular-expressions.info/email.html а>
from validate_email import validate_email
is_valid = validate_email('[email protected]',verify=True)
print(bool(is_valid))
Адреса электронной почты невероятно сложны. Вот пример регулярного выражения, которое будет соответствовать каждому допустимому адресу RFC822: http://www.ex-parrot.com/pdw/Mail-RFC822-Address.html
Вы заметите, что это, вероятно, длиннее, чем остальная часть вашей программы. Существуют даже целые модули для Perl с целью проверки адресов электронной почты. Таким образом, вы, вероятно, не получите ничего, что было бы на 100% идеальным в качестве регулярного выражения, но при этом было бы читабельным. Вот пример парсера рекурсивного спуска: http://cpansearch.perl.org/src/ABIGAIL/RFC-RFC822-Address-2009110702/lib/RFC/RFC822/Address.pm
но вам нужно решить, нужен ли вам идеальный синтаксический анализ или простой код.
Если вы хотите извлечь почту из длинной строки или файла, попробуйте это.
([^@|\s]+@[^@]+\.[^@|\s]+)
Обратите внимание, это сработает, если у вас есть пробел до и после вашего адреса электронной почты. если у вас нет места или у вас есть специальные символы, вы можете попробовать изменить его.
Рабочий пример:
string="Hello ABCD, here is my mail id [email protected] "
res = re.search("([^@|\s]+@[^@]+\.[^@|\s]+)",string,re.I)
res.group(1)
Это уберет [email protected]
из этой строки.
Также обратите внимание, что это может быть неправильный ответ ... Но я разместил его здесь, чтобы помочь кому-то, у кого есть особые требования, такие как я.
Для проверки электронной почты используйте email_validator.
from email_validator import validate_email, EmailNotValidError
def check_email(email):
try:
v = validate_email(email) # validate and get info
email = v["email"] # replace with normalized form
print("True")
except EmailNotValidError as e:
# email is not valid, exception message is human-readable
print(str(e))
check_email("test@gmailcom")
Используйте эту маску фильтра при вводе электронной почты: emailMask: /[\w.\-@'"!#$%&'*+/=?^_
{|} ~] / i`
Поиск идентификатора электронной почты:
import re
a=open("aa.txt","r")
#c=a.readlines()
b=a.read()
c=b.split("\n")
print(c)
for d in c:
obj=re.search(r'[\w.]+\@[\w.]+',d)
if obj:
print(obj.group())
#for more calcification click on image above..
Нашел, что это практическая реализация:
[^@\s]+@[^@\s]+\.[^@\s]+
[^@\s]+@[^@\s]+\.[^@\s]+
Это неверно, потому что это позволит использовать пробелы в части расширения .c om
, а пробелы в электронных письмах не допускаются.
- person WayBehind; 17.04.2020
r.match
и re.compile
для тестирования, а не re.findall
, поэтому, возможно, мы оба правы, если используются по назначению. К сожалению, вы не предоставили никаких подробностей в своем ответе, и поэтому он был открыт для недопонимания. Если вы отредактируете свой ответ, я смогу убрать голос против. К сожалению, без редактирования вашего ответа система не позволит мне изменить свой голос.
- person WayBehind; 20.04.2020
проверка электронной почты
import re
def validate(email):
match=re.search(r"(^[a-zA-Z0-9_.+-]+@[a-zA-Z0-9]+\.[a-zA-Z0-9.]*\.*[com|org|edu]{3}$)",email)
if match:
return 'Valid email.'
else:
return 'Invalid email.'
Единственный действительно точный способ отличить действительные действительные адреса электронной почты от недействительных - это отправить на него почту. То, что считается электронной почтой, на удивление запутано ("John Doe" <[email protected]>"
на самом деле является действительным адресом электронной почты), и вы, скорее всего, захотите, чтобы адрес электронной почты действительно отправлял на него почту позже. После того, как он пройдет некоторые базовые проверки работоспособности (например, в ответе Томаса есть @
и хотя бы один .
после @
), вам, вероятно, следует просто отправить письмо с подтверждением по электронной почте на адрес и дождаться, пока пользователь перейдет по встроенной ссылке в сообщении, чтобы подтвердить, что адрес электронной почты действителен.
return re.search("^[\w\.\+\-]+\@[\w]+\.[a-z]{2,3}$", email) != None
- person Vladimir; 24.05.2020