Z biegiem lat powoli opracowałem wyrażenie regularne, które poprawnie weryfikuje MOST adresy e-mail, zakładając, że nie używają adresu IP jako części serwera.
Używam go w kilku programach PHP i działa przez większość czasu. Jednak od czasu do czasu kontaktuję się z kimś, kto ma problem z witryną, która z niego korzysta, i ostatecznie muszę wprowadzić pewne poprawki (ostatnio zdałem sobie sprawę, że nie zezwalam na 4-znakowe domeny TLD).
Jakie jest najlepsze wyrażenie regularne, które znasz lub widziałeś do sprawdzania poprawności wiadomości e-mail?
Widziałem kilka rozwiązań wykorzystujących funkcje, które wykorzystują kilka krótszych wyrażeń, ale wolę mieć jedno długie złożone wyrażenie w prostej funkcji zamiast kilku krótkich wyrażeń w bardziej złożonej funkcji.
źródło
Odpowiedzi:
Wyrażenie regularne w pełni zgodne z RFC 822 jest nieefektywne i niejasne ze względu na swoją długość. Na szczęście RFC 822 został dwukrotnie zastąpiony, a obecna specyfikacja adresów e-mail to RFC 5322 . RFC 5322 prowadzi do wyrażenia regularnego, który można zrozumieć, jeśli zostanie zbadany przez kilka minut i jest wystarczająco wydajny do faktycznego użycia.
Jedno wyrażenie regularne zgodne z RFC 5322 można znaleźć na górze strony pod adresem http://emailregex.com/, ale używa wzorca adresu IP, który unosi się w Internecie z błędem, który pozwala
00
na dowolną z wartości dziesiętnych bajtu bez znaku w adres rozdzielany kropkami, co jest nielegalne. Reszta wydaje się być zgodna z gramatyką RFC 5322 i przechodzi kilka testów przy użyciugrep -Po
, w tym nazw domen, adresów IP, złych adresów i nazw kont z cudzysłowami i bez nich.Korygując
00
błąd we wzorcu IP, otrzymujemy działający i dość szybki regex. (Złap renderowaną wersję, a nie obniżkę, dla rzeczywistego kodu.)lub:
Oto schemat z automatem skończonym do powyższego wyrażenia regularnego, które jest bardziej oczywiste niż sama regexp
Bardziej wyrafinowane wzorce w Perlu i PCRE (biblioteka wyrażeń regularnych używanych np. W PHP) mogą poprawnie parsować RFC 5322 bez żadnych problemów . Python i C # też mogą to zrobić, ale używają innej składni niż te pierwsze dwa. Jeśli jednak musisz użyć jednego z wielu słabszych języków dopasowywania wzorców, najlepiej użyć prawdziwego analizatora składni.
Ważne jest również, aby zrozumieć, że sprawdzenie go zgodnie z RFC nie mówi absolutnie nic o tym, czy ten adres faktycznie istnieje w dostarczonej domenie, czy też osoba wpisująca adres jest jego prawdziwym właścicielem. Ludzie cały czas zapisują innych na listy mailingowe. Naprawianie wymagające bardziej wymyślnego sprawdzania poprawności, które polega na wysłaniu na ten adres wiadomości zawierającej token potwierdzający, który należy wprowadzić na tej samej stronie internetowej, co adres.
Tokeny potwierdzające to jedyny sposób, aby dowiedzieć się, czy masz adres osoby, która do niego wchodzi. Dlatego większość list mailingowych używa teraz tego mechanizmu do potwierdzania rejestracji. W końcu każdy może odłożyć
[email protected]
, a to nawet będzie traktowane jako legalne, ale prawdopodobnie nie będzie to osoba na drugim końcu.PHP, należy nie używać wzoru podanego w Weryfikuj adres e-mail z PHP, Right Way , z którego cytuję:
Nie jest to lepsze niż wszystkie inne wzorce inne niż RFC. Nie jest nawet wystarczająco inteligentny, aby obsługiwać nawet RFC 822 , a tym bardziej RFC 5322. Ten jednak jest.
Jeśli chcesz uzyskać fantazyjny i pedantyczny, zaimplementuj kompletny silnik stanowy . Wyrażenie regularne może działać tylko jako podstawowy filtr. Problem z wyrażeniami regularnymi polega na tym, że mówienie komuś, że jego idealnie poprawny adres e-mail jest nieprawidłowy (fałszywie dodatni), ponieważ twoje wyrażenie regularne nie może sobie z tym poradzić, jest po prostu niegrzeczne i niegrzeczne z punktu widzenia użytkownika. Mechanizm stanowy do tego celu może zarówno sprawdzać poprawność, a nawet poprawiać adresy e-mail, które w innym przypadku zostałyby uznane za nieprawidłowe, ponieważ dezasembluje adres e-mail zgodnie z każdym RFC. Pozwala to na potencjalnie bardziej przyjemne wrażenia, takie jak
Zobacz także Sprawdzanie poprawności adresów e-mail , w tym komentarzy. Lub porównanie adresu e-mail sprawdzającego poprawność wyrażeń regularnych .
Demo Debuggex
źródło
Nie należy używać wyrażeń regularnych do sprawdzania poprawności adresów e-mail.
Zamiast tego użyj klasy MailAddress , jak poniżej:
MailAddress
Klasa wykorzystuje parser BNF, aby sprawdzić poprawność adresu w pełni zgodne z rfc822.Jeśli planujesz użyć
MailAddress
adresu e-mail do sprawdzenia poprawności adresu e-mail, pamiętaj, że to podejście akceptuje również część nazwy wyświetlanej adresu e-mail i może to nie być dokładnie to, co chcesz osiągnąć. Na przykład akceptuje te ciągi jako prawidłowe adresy e-mail:W niektórych przypadkach tylko ostatnia część ciągów jest analizowana jako adres; reszta przed tym jest nazwą wyświetlaną. Aby uzyskać zwykły adres e-mail bez nazwy wyświetlanej, możesz sprawdzić znormalizowany adres względem oryginalnego ciągu.
Ponadto adres z kropką na końcu, podobnie jak,
user@company.
jest również akceptowany przez MailAddress.Jeśli naprawdę chcesz użyć wyrażenia regularnego, oto on :
źródło
[email protected]
. Nie można polegać na sprawdzaniu poprawności wiadomości e-mail, aby zapobiec XSS.To pytanie jest często zadawane, ale myślę, że powinieneś cofnąć się i zadać sobie pytanie, dlaczego chcesz zweryfikować składniowo adresy e-mail? Jaka jest tak naprawdę korzyść?
Jeśli chcesz sprawdzić poprawność wiadomości e-mail, nie masz innego wyboru, jak wysłać wiadomość e-mail z potwierdzeniem i poprosić użytkownika o odpowiedź. W wielu przypadkach będziesz musiał mimo to wysłać wiadomość potwierdzającą ze względów bezpieczeństwa lub ze względów etycznych (więc nie możesz np. Zapisać się do usługi wbrew jej woli).
źródło
me@hotmail
, to oczywiście nie dostanie e-maila z potwierdzeniem, a potem gdzie on jest? Nie ma ich już w Twojej witrynie i zastanawiają się, dlaczego nie mogli się zarejestrować. Właściwie nie, nie są - zupełnie o tobie zapomnieli. Jeśli jednak możesz po prostu wykonać podstawowe sprawdzenie poprawności za pomocą wyrażenia regularnego, gdy wciąż są one przy tobie, mogą od razu wykryć ten błąd i masz szczęśliwego użytkownika.[email protected]
adresy wskazują na bardzo zajętego wodza naczelnego. :)Wszystko zależy od tego, jak dokładny chcesz być. Do moich celów, gdzie staram się po prostu unikać takich rzeczy
bob @ aol.com
(spacje w wiadomościach e-mail) lubsteve
(w ogóle nie ma domeny) lubmary@aolcom
(bez okresu przed .com), używamJasne, pasuje do rzeczy, które nie są prawidłowymi adresami e-mail, ale jest to kwestia uzyskania typowych prostych błędów.
Istnieje wiele zmian, które można wprowadzić w tym wyrażeniu regularnym (niektóre z nich znajdują się w komentarzach do tej odpowiedzi), ale jest to proste i łatwe do zrozumienia i jest dobrą pierwszą próbą.
źródło
.
jest zawarty w\S
.mary@aolcom
całkowitym śmieciu , YMMV@
znaki:/^[^\s@]+@[^\s@]+\.[^\s@]{2,}$/
jsfiddle.net/b9chris/mXB96To zależy od tego, co masz na myśli: Jeśli chodzi o przechwytywanie każdego prawidłowego adresu e-mail, użyj następujących elementów:
( http://www.ex-parrot.com/~pdw/Mail-RFC822-Address.html ) Jeśli szukasz czegoś prostszego, ale umożliwi to przechwycenie większości prawidłowych adresów e-mail, spróbuj czegoś takiego:
EDYCJA: Z linku:
źródło
email address
które błędnie przechodzą przez drugi, ale są łapane przez dłuższe wyrażenie regularne?[ZAKTUALIZOWANO] Tutaj zebrałem wszystko, co wiem o sprawdzaniu poprawności adresu e-mail: http://isemail.info , który teraz nie tylko sprawdza poprawność, ale także diagnozuje problemy z adresami e-mail. Zgadzam się z wieloma komentarzami tutaj, że zatwierdzenie jest tylko częścią odpowiedzi; zobacz mój esej na http://isemail.info/about .
is_email () pozostaje, o ile wiem, jedynym walidatorem, który ostatecznie powie ci, czy dany ciąg jest prawidłowym adresem e-mail, czy nie. Przesłałem nową wersję na http://isemail.info/
Zebrałem przypadki testowe od Cal Henderson, Dave Child, Phil Haack, Doug Lovell, RFC5322 i RFC 3696. W sumie 275 adresów testowych. Przeprowadziłem wszystkie te testy dla wszystkich darmowych walidatorów, jakie mogłem znaleźć.
Postaram się aktualizować tę stronę, gdy ludzie ulepszają swoje moduły sprawdzające poprawność. Dziękuję Calowi, Michaelowi, Dave'owi, Paulowi i Philowi za ich pomoc i współpracę przy opracowywaniu tych testów oraz konstruktywną krytykę mojego własnego weryfikatora .
Ludzie powinni być świadomi erraty w szczególności przeciwko RFC 3696 . Trzy z kanonicznych przykładów są w rzeczywistości nieprawidłowymi adresami. Maksymalna długość adresu to 254 lub 256 znaków, a nie 320.
źródło
[email protected]
ponieważ ten kod dotyczy sprawdzania poprawności, a nie interpretacji. Jeśli chcesz dodać tłumacz kodów kreskowych, zZgodnie ze specyfikacją W3C HTML5 :
Kontekst:
źródło
john.doe@localhost
jest poprawny. Na pewno w aplikacji w świecie rzeczywistym (tj. Społeczności) chciałbym, aby twoja sugestia zastąpiła * +"test...."@gmail.com
jest całkowicie poprawny zgodnie z RFC i semantycznie równoważny[email protected]
.W Perlu 5.10 lub nowszym jest to łatwe:
źródło
addrspec
części jest naprawdę istotny dla pytania. Zaakceptowanie czegoś więcej i przekazanie go przez inną część systemu, która nie jest gotowa na przyjęcie pełnych adresów RFC5822, jest jak strzelanie własną stopą.używam
Który jest używany w ASP.NET przez RegularExpressionValidator.
źródło
[email protected]
został odrzucony.^\\w+([-+.']\\w+)*@\\w+([-.]\\w+)*\\.\\w{2,}([-.]\\w+)*$
[email protected]
co w rzeczywistości jest ważne (nasz klient miał podobny adres) `Nie wiem najlepiej, ale ten jest co najmniej poprawny, pod warunkiem, że adresy zostały usunięte i zastąpione białymi spacjami.
Poważnie. Powinieneś użyć już napisanej biblioteki do sprawdzania poprawności wiadomości e-mail. Najlepszym sposobem jest prawdopodobnie wysłanie e-maila weryfikacyjnego na ten adres.
źródło
Adresy e-mail, które chcę sprawdzić, będą używane przez aplikację sieci Web ASP.NET za pomocą przestrzeni nazw System.Net.Mail do wysyłania wiadomości e-mail do listy osób. Zamiast więc używać bardzo złożonego wyrażenia regularnego, po prostu próbuję utworzyć instancję MailAddress z adresu. Konstruktor MailAddress zgłosi wyjątek, jeśli adres nie zostanie poprawnie utworzony. W ten sposób wiem, że mogę przynajmniej wyciągnąć wiadomość e-mail z drzwi. Oczywiście jest to sprawdzanie poprawności po stronie serwera, ale i tak potrzebujesz tego przynajmniej.
źródło
args.Value
zamiast odwoływania się do pola natxtEmail.Text
sztywno. Ten ostatni powiąże twój walidator z pojedynczą instancją kontrolną, co może być OK, o ile masz jedno pole e-mail, ale nie jest zalecane inaczej.Szybka odpowiedź
Użyj następującego wyrażenia regularnego do sprawdzania poprawności danych wejściowych:
([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)+
Adresy pasujące do tego wyrażenia regularnego:
Drugim ograniczeniem jest ograniczenie RFC 5321/5322.
Opracuj odpowiedź
Użycie wyrażenia regularnego, które rozpoznaje adresy e-mail, może być przydatne w różnych sytuacjach: na przykład do skanowania adresów e-mail w dokumencie, do sprawdzania poprawności danych wprowadzanych przez użytkownika lub jako ograniczenia integralności repozytorium danych.
Należy jednak zauważyć, że jeśli chcesz dowiedzieć się, czy adres faktycznie odnosi się do istniejącej skrzynki pocztowej, nic nie zastąpi wysłania wiadomości na ten adres. Jeśli chcesz tylko sprawdzić, czy adres jest poprawny gramatycznie, możesz użyć wyrażenia regularnego, ale pamiętaj o tym
""@[]
jest to poprawny gramatycznie adres e-mail, który z pewnością nie odnosi się do istniejącej skrzynki pocztowej.Składnia adresów e-mail została zdefiniowana w różnych dokumentach RFC , w szczególności w dokumentach RFC 822 i RFC 5322 . RFC 822 należy postrzegać jako „oryginalny” standard, a RFC 5322 jako najnowszy standard. Składnia zdefiniowana w RFC 822 jest najbardziej łagodna, a kolejne standardy jeszcze bardziej ją ograniczały, w których nowsze systemy lub usługi powinny rozpoznawać przestarzałą składnię, ale nigdy jej nie produkować.
W tej odpowiedzi wezmę „adres e-mail” w znaczeniu
addr-spec
zdefiniowanym w RFC (tj.[email protected]
Ale nie"John Doe"<[email protected]>
, anisome-group:[email protected],[email protected];
).Jest jeden problem z tłumaczeniem składni RFC na wyrażenia regularne: składnie nie są regularne! Wynika to z faktu, że pozwalają one na opcjonalne komentarze w adresach e-mail, które mogą być nieskończenie zagnieżdżone, podczas gdy nieskończonego zagnieżdżenia nie można opisać wyrażeniem regularnym. Aby wyszukać lub sprawdzić adresy zawierające komentarze, potrzebujesz analizatora składni lub bardziej zaawansowanych wyrażeń. (Zauważ, że języki takie jak Perl mają konstrukcje opisujące gramatykę bezkontekstową w sposób wyrażenia regularnego.) W tej odpowiedzi zignoruję komentarze i rozważę tylko właściwe wyrażenia regularne.
RFC definiują składnie wiadomości e-mail, a nie adresów jako takich. Adresy mogą pojawiać się w różnych polach nagłówka i tutaj są one przede wszystkim zdefiniowane. Gdy pojawiają się w polach nagłówka, adresy mogą zawierać (między tokenami leksykalnymi) spacje, komentarze, a nawet podziały wierszy. Semantycznie nie ma to jednak znaczenia. Usuwając ten biały znak itp. Z adresu, otrzymujesz semantycznie równoważną reprezentację kanoniczną . Zatem kanoniczna reprezentacja
first. last (comment) @ [3.5.7.9]
jestfirst.last@[3.5.7.9]
.Do różnych celów należy stosować różne składnie. Jeśli chcesz skanować w poszukiwaniu adresów e-mail w (być może bardzo starym) dokumencie, dobrym pomysłem może być użycie składni zdefiniowanej w RFC 822. Z drugiej strony, jeśli chcesz zweryfikować dane wprowadzone przez użytkownika, możesz użyć składnia zgodnie z definicją w RFC 5322, prawdopodobnie przyjmując tylko reprezentacje kanoniczne. Powinieneś zdecydować, która składnia ma zastosowanie do konkretnego przypadku.
W tej odpowiedzi używam „rozszerzonych” wyrażeń regularnych POSIX, zakładając, że zestaw znaków jest zgodny z ASCII.
RFC 822
Doszedłem do następującego wyrażenia regularnego. Zapraszam wszystkich do spróbowania go złamać. Jeśli znajdziesz jakieś fałszywie pozytywne lub fałszywe negatywy, opublikuj je w komentarzu, a ja postaram się naprawić wyrażenie tak szybko, jak to możliwe.
([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*")(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|"(\n|(\\\r)*([^"\\\r\n]|\\[^\r]))*(\\\r)*"))*@([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*])(\.([^][()<>@,;:\\". \x00-\x1F\x7F]+|\[(\n|(\\\r)*([^][\\\r\n]|\\[^\r]))*(\\\r)*]))*
Uważam, że jest w pełni zgodny z RFC 822, w tym z erratą . Rozpoznaje tylko adresy e-mail w formie kanonicznej. Dla wyrażenia regularnego, które rozpoznaje (składanie) białych znaków, zobacz pochodną poniżej.
Wyprowadzenie pokazuje, jak doszedłem do wyrażenia. Podaję wszystkie odpowiednie reguły gramatyczne z RFC dokładnie tak, jak się pojawiają, a następnie odpowiadające im wyrażenie regularne. Tam, gdzie opublikowano erratę, podaję osobne wyrażenie dla poprawionej reguły gramatyki (oznaczonej jako „erratum”) i używam zaktualizowanej wersji jako podwyrażenia w kolejnych wyrażeniach regularnych.
Jak stwierdzono w pkt 3.1.4. RFC 822 opcjonalną liniową spację można wstawić między tokeny leksykalne. W stosownych przypadkach rozszerzyłem wyrażenia, aby uwzględnić tę regułę i oznaczyłem wynik jako „opt-lwsp”.
RFC 5322
Doszedłem do następującego wyrażenia regularnego. Zapraszam wszystkich do spróbowania go złamać. Jeśli znajdziesz jakieś fałszywie pozytywne lub fałszywe negatywy, opublikuj je w komentarzu, a ja postaram się naprawić wyrażenie tak szybko, jak to możliwe.
([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|\[[\t -Z^-~]*])
Uważam, że jest w pełni zgodny z RFC 5322, w tym z erratą . Rozpoznaje tylko adresy e-mail w formie kanonicznej. Dla wyrażenia regularnego, które rozpoznaje (składanie) białych znaków, zobacz pochodną poniżej.
Wyprowadzenie pokazuje, jak doszedłem do wyrażenia. Podaję wszystkie odpowiednie reguły gramatyczne z RFC dokładnie tak, jak się pojawiają, a następnie odpowiadające im wyrażenie regularne. Dla reguł, które zawierają semantycznie nieistotne (składane) białe spacje, podaję osobne wyrażenie regularne oznaczone „(znormalizowane)”, które nie akceptuje tej białej spacji.
Zignorowałem wszystkie zasady „obs-” z RFC. Oznacza to, że wyrażenia regularne pasują tylko do adresów e-mail ściśle zgodnych z RFC 5322. Jeśli musisz dopasować „stare” adresy (jak robi to luźniejsza gramatyka, w tym reguły „obs-”), możesz użyć jednego z wyrażeń regularnych RFC 822 z poprzedniego akapitu.
Zauważ, że niektóre źródła (zwłaszcza w3c ) twierdzą, że RFC 5322 jest zbyt rygorystyczny dla części lokalnej (tj. Części przed znakiem @). Jest tak, ponieważ „..”, „a..b” i „a.” nie są poprawnymi atomami-kropkami, chociaż mogą być używane jako nazwy skrzynek pocztowych. RFC, jednakże nie pozwalają na lokalne części takich jak te, oprócz tego, że muszą one być podane. Zamiast tego
[email protected]
powinieneś pisać"a..b"@example.net
, co jest semantycznie równoważne.Dalsze ograniczenia
SMTP (zgodnie z definicją w RFC 5321 ) dodatkowo ogranicza zestaw prawidłowych adresów e-mail (a właściwie: nazwy skrzynek pocztowych). Narzucenie tej surowszej gramatyki wydaje się rozsądne, aby dopasowany adres e-mail mógł faktycznie zostać użyty do wysłania wiadomości e-mail.
RFC 5321 w zasadzie pozostawia samą część „lokalną” (tj. Część przed znakiem @), ale jest bardziej rygorystyczna w części domeny (tj. Część po znaku @). Pozwala tylko na nazwy hostów zamiast atomów kropkowych i literałów adresowych zamiast literałów domenowych.
Gramatyka przedstawiona w RFC 5321 jest zbyt łagodna, jeśli chodzi zarówno o nazwy hostów, jak i adresy IP. Pozwoliłem sobie na „poprawienie” omawianych zasad, wykorzystując ten projekt i RFC 1034 jako wytyczne. Oto wynikowe wyrażenie regularne.
([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)*|\[((25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3}|IPv6:((((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){6}|::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){5}|[0-9A-Fa-f]{0,4}::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){4}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):)?(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){3}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,2}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){2}|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,3}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,4}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])(\.(25[0-5]|2[0-4][0-9]|1[0-9]{2}|[1-9]?[0-9])){3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,5}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3})|(((0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}):){0,6}(0|[1-9A-Fa-f][0-9A-Fa-f]{0,3}))?::)|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+)])
Zauważ, że w zależności od przypadku użycia możesz nie chcieć dopuścić „dosłowny adres ogólny” w wyrażeniu regularnym. Zauważ też, że użyłem negatywnego spojrzenia
(?!IPv6:)
w ostatnim wyrażeniu regularnym, aby zapobiec części „dosłowny adres-dosłowny”, aby dopasować zniekształcone adresy IPv6. Niektóre procesory wyrażeń regularnych nie obsługują negatywnego wyglądu. Usuń podciąg|(?!IPv6:)[0-9A-Za-z-]*[0-9A-Za-z]:[!-Z^-~]+
z wyrażenia regularnego, jeśli chcesz usunąć całą część „Ogólny adres-dosłowny”.Oto pochodna:
Sprawdzanie poprawności przez użytkownika
Typowym przypadkiem użycia jest sprawdzanie poprawności przez użytkownika, na przykład w formularzu HTML. W takim przypadku zwykle uzasadnione jest wykluczenie literałów adresu i wymaganie co najmniej dwóch etykiet w nazwie hosta. Biorąc za podstawę ulepszoną regex RFC 5321 z poprzedniej sekcji, wynikowe wyrażenie byłoby:
([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)+
Nie polecam dalszego ograniczania części lokalnej, np. Poprzez wykluczenie ciągów cytowanych, ponieważ nie wiemy, jakie nazwy skrzynek pocztowych są dozwolone przez niektóre hosty (jak,
"a..b"@example.net
a nawet"a b"@example.net
).Nie polecam też jawnego sprawdzania poprawności listy dosłownych domen najwyższego poziomu ani nawet nakładania ograniczeń długości (pamiętaj, jak unieważniono „.museum”
[a-z]{2,4}
), ale jeśli musisz:([-!#-'*+/-9=?A-Z^-~]+(\.[-!#-'*+/-9=?A-Z^-~]+)*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@([0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?\.)*(net|org|com|info|
itp...)
Upewnij się, że regex jest aktualny, jeśli zdecydujesz się pójść ścieżką jawnej weryfikacji domeny najwyższego poziomu.
Dalsze uwagi
Przy akceptowaniu tylko nazw hostów w części domeny (po znaku @) powyższe wyrażenia regularne akceptują tylko etykiety zawierające maksymalnie 63 znaki, tak jak powinny. Nie wymuszają jednak faktu, że cała nazwa hosta musi mieć co najwyżej 253 znaki (łącznie z kropkami). Chociaż ograniczenie to jest ściśle mówiąc nadal regularne, nie jest możliwe wykonanie wyrażenia regularnego uwzględniającego tę zasadę.
Innym zagadnieniem, szczególnie w przypadku używania wyrażeń regularnych do sprawdzania poprawności danych wejściowych, jest informacja zwrotna dla użytkownika. Jeśli użytkownik wprowadzi niepoprawny adres, dobrze byłoby przekazać nieco więcej informacji zwrotnych niż prosty „adres niepoprawny pod względem składniowym”. W przypadku wyrażeń regularnych „waniliowych” nie jest to możliwe.
Te dwie kwestie można rozwiązać, analizując adres. Dodatkowym ograniczeniem długości nazw hostów można w niektórych przypadkach również zaradzić, używając dodatkowego wyrażenia regularnego, które to sprawdza, i dopasowując adres do obu wyrażeń.
Żadne z wyrażeń regularnych w tej odpowiedzi nie jest zoptymalizowanych pod kątem wydajności. Jeśli wydajność stanowi problem, powinieneś sprawdzić, czy (i jak) wybrany regex można zoptymalizować.
źródło
arbitrary-long-email-address-should-be-invalid-arbitrary-long-email-address-should-be-invalid.and-the-second-group-also-should-not-be-so-long-and-the-second-group-also-should-not-be-so-long@example.com
nie powinien sprawdzać poprawności. Sugeruję zmianę znaków „+” w pierwszej grupie (nazwa przed opcjonalną kropką) oraz w drugiej grupie (nazwa po następujących kropkach) na{1,64}
$emailRegex = '/^([-!#-\'*+\/-9=?A-Z^-~]{1,64}(\.[-!#-\'*+\/-9=?A-Z^-~]{1,64})*|"([]!#-[^-~ \t]|(\\[\t -~]))+")@[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?(\.[0-9A-Za-z]([0-9A-Za-z-]{0,61}[0-9A-Za-z])?)+$/';
Istnieje wiele przykładów tego w sieci (i myślę, że nawet taki, który w pełni zatwierdza RFC - ale jeśli dziesiątki / setki linii są długie, jeśli pamięć służy). Ludzie zwykle dają się ponieść próbom potwierdzenia tego rodzaju rzeczy. Dlaczego nie sprawdzić, czy ma @ i przynajmniej jeden. i spełnia pewną minimalną długość. Podanie fałszywego adresu e-mail i mimo to dopasowanie go do dowolnego prawidłowego wyrażenia regularnego jest banalne. Domyślam się, że fałszywie pozytywne są lepsze niż fałszywe negatywy.
źródło
Decydując, które postacie są dozwolone, pamiętaj o swoich apostrofach i dzielonych znajomych. Nie mam kontroli nad tym, że moja firma generuje mój adres e-mail, używając mojego nazwiska z systemu HR. Obejmuje to apostrof w moim nazwisku. Nie mogę powiedzieć, ile razy blokowano mi interakcję z witryną przez fakt, że mój adres e-mail jest „nieprawidłowy”.
źródło
Ten regex pochodzi z biblioteki Email :: Valid w Perlu . Uważam, że jest najdokładniejszy, pasuje do wszystkich 822. Opiera się na wyrażeniu regularnym z książki O'Reilly:
źródło
Podczas pisania w PHP radzę korzystać z walidacji wbudowanej PHP dla wiadomości e-mail.
Jeśli używasz wersji php niższej niż 5.3.6, pamiętaj o tym problemie: https://bugs.php.net/bug.php?id=53091
Jeśli chcesz uzyskać więcej informacji o tym, jak działa sprawdzanie poprawności, zobacz tutaj: Czy PHP filter_var FILTER_VALIDATE_EMAIL faktycznie działa?
źródło
Cal Henderson (Flickr) napisał artykuł o nazwie Przetwarzanie adresów e-mail w PHP i pokazuje, jak poprawnie parsować adresy e-mail zgodne z RFC (2) 822. Możesz również pobrać kod źródłowy w php , python i ruby, który jest na licencji CC .
źródło
a@b
to ważnea@b
jest poprawny ... w tym przypadkub
jest to domena najwyższego poziomu.Nigdy nie zawracam sobie głowy tworzeniem z moim wyrażeniem regularnym, ponieważ są szanse, że ktoś inny wymyślił już lepszą wersję. Zawsze używam wyrażenia regularnego, aby znaleźć taki, który mi się podoba.
źródło
Nie ma takiego, który byłby naprawdę użyteczny.
Omawiam niektóre problemy w odpowiedzi na pytanie Czy jest biblioteka php do sprawdzania poprawności adresu e-mail? , jest to omawiane również w przypadku rozpoznawania adresu e-mail przez Regexp?
Krótko mówiąc, nie oczekuj, że jeden, użyteczny wyrażenie regularne wykona odpowiednią pracę. A najlepsze wyrażenie regularne potwierdzi składnię, a nie poprawność wiadomości e-mail (adres [email protected] jest poprawny, ale prawdopodobnie zostanie odrzucony ...).
źródło
Jednym prostym wyrażeniem regularnym, które przynajmniej nie odrzucałoby żadnego prawidłowego adresu e-mail, byłoby sprawdzanie czegoś, po którym następuje znak @, a następnie coś, po którym następuje kropka i co najmniej 2 coś. Nie odrzuci niczego, ale po zapoznaniu się ze specyfikacją nie mogę znaleźć żadnego e-maila, który byłby prawidłowy i odrzucony.
email = ~
/.+@[^@]+\.[^@]{2,}$/
źródło
/^[^@]+@[^@]+\.[^@]{2}[^@]*$/
faktycznie sprawdza znak 1 @. Twoje wyrażenie regularne przepuści wiele razy z powodu. * Na końcu./^[^@]+@[^@]+\.[^@]{2,4}$/
upewniając się, że kończy się na 2 do 4 znakach innych niż @. Jak zauważył @Josh, teraz na końcu pozwala na dodatkowe @. Ale możesz to również zmienić na:/^[^@]+@[^@]+\.[^a-z-A-Z]{2,4}$/
ponieważ wszystkie domeny najwyższego poziomu są znakami aZ. można wymienić4
z5
lub bardziej pozwalając nazw domen najwyższego poziomu będzie już w przyszłości.Możesz użyć tego zastosowanego przez wtyczkę jQuery Validation:
źródło
a-b'[email protected]
ale był w stanie wychwycić nieodpowiednie odmiany, takie jaka-b'[email protected]
ia-b'[email protected]
Aby uzyskać najbardziej kompleksową ocenę najlepszego wyrażenia regularnego do sprawdzania poprawności adresu e-mail, zobacz ten link; „ Porównywanie adresu e-mail sprawdzającego poprawność wyrażeń regularnych ”
Oto aktualne najważniejsze wyrażenie w celach informacyjnych:
źródło
Nie wspominając już o tym, że nazwy domen innych niż łacińskie (chińskie, arabskie, greckie, hebrajskie, cyrylica itp.) Będą dozwolone w najbliższej przyszłości . Każdy musi zmienić używane wyrażenie regularne, ponieważ te znaki z pewnością nie będą objęte
[a-z]/i
ani\w
. Wszystkie zawiodą.W końcu najlepszym sposobem na sprawdzenie adresu e-mail jest nadal wysłanie wiadomości e-mail na ten adres w celu potwierdzenia adresu. Jeśli adres e-mail jest częścią uwierzytelnienia użytkownika (rejestracja / login / etc), możesz idealnie połączyć go z systemem aktywacji użytkownika. To znaczy, wyślij e-mail z linkiem z unikalnym kluczem aktywacyjnym na podany adres e-mail i zezwól na logowanie tylko wtedy, gdy użytkownik aktywuje nowo utworzone konto za pomocą linku w e-mailu.
Jeśli celem wyrażenia regularnego jest po prostu szybkie poinformowanie użytkownika w interfejsie użytkownika, że podany adres e-mail nie wygląda we właściwym formacie, najlepiej sprawdzić, czy odpowiada on zasadniczo poniższemu wyrażeniu regularnemu:
Proste. Dlaczego, do cholery, miałbyś przejmować się postaciami używanymi w nazwie i domenie? Obowiązkiem klienta jest podanie prawidłowego adresu e-mail, a nie serwera. Nawet jeśli klient poda poprawny składniowo adres e-mail
[email protected]
, taki jak , nie gwarantuje to, że jest to prawidłowy adres e-mail. Nikt regex nie może tego pokryć.źródło
spaces
na@.
np. po .[email protected] com net
uważa poprawny adres e-mail za pomocą powyższego wyrażenia regularnego, ponieważ powinien on zwracać nieprawidłowy.Specyfikacja HTML5 sugeruje proste wyrażenie regularne do sprawdzania poprawności adresów e-mail:
Celowo nie jest to zgodne z RFC 5322 .
Całkowita długość może być również ograniczona do 254 znaków na RFC 3696 errata 1690 .
źródło
invalid@emailaddress
. Nalegam na ostrożność i wiele testów przed użyciem!Dla żywej demonstracji następujący potwór jest całkiem niezły, ale nadal nie rozpoznaje poprawnie wszystkich składniowo ważnych adresów e-mail: rozpoznaje zagnieżdżone komentarze o głębokości do czterech poziomów.
Jest to zadanie dla analizatora składni, ale nawet jeśli adres jest poprawny pod względem składniowym, nadal może nie być dostarczalny. Czasami musisz zastosować metodę Hillbilly: „Hej, wszyscy, patrzcie na nas!”
źródło
Zgodnie z oficjalnym standardem RFC 2822 poprawny wyrazy e-mail to
jeśli chcesz go używać w Javie, to naprawdę bardzo proste
źródło
(?:[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[A-Za-z0-9!#$%&'*+/=?^_`{|}~-]+)*|"(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21\x23-\x5b\x5d-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])*")@(?:(?:[a-z0-9](?:[a-z0-9-]*[a-z0-9])?\.)+[a-z0-9](?:[a-z0-9-]*[a-z0-9])?|\[(?:(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?)\.){3}(?:25[0-5]|2[0-4][0-9]|[01]?[0-9][0-9]?|[a-z0-9-]*[a-z0-9]:(?:[\x01-\x08\x0b\x0c\x0e-\x1f\x21-\x5a\x53-\x7f]|\\[\x01-\x09\x0b\x0c\x0e-\x7f])+)\])
Oto PHP, którego używam. Wybrałem to rozwiązanie w duchu „fałszywe pozytywy są lepsze niż fałszywe negatywy”, jak zadeklarował inny komentator ORAZ odnośnie utrzymania czasu odpowiedzi i obciążenia serwera ... naprawdę nie trzeba marnować zasobów serwera wyrażenie regularne, gdy wyeliminuje to najprostszy błąd użytkownika. W razie potrzeby zawsze możesz to zrobić, wysyłając testową wiadomość e-mail.
źródło
Standard RFC 5322:
Umożliwia część lokalną dot-atom, część lokalną z cytowanym ciągiem, przestarzałą (mieszaną część kropkową i ciąg cytowany) część lokalną, domenę domeny, (IPv4, IPv6 i adres IPv6 odwzorowany na IPv6) domenę dosłowną, i (zagnieżdżony) CFWS.
Standard RFC 5321:
Pozwala na lokalną część kropkową, część lokalną z cytowanym ciągiem, domenę nazw domen i (dosł. IPv4, IPv6 i adres IPv6 odwzorowany na IPv4) domenę.
Podstawowy:
Umożliwia dot-atom lokalną część i nazwę domeny (wymaga co najmniej dwóch etykiet nazw domen z TLD ograniczoną do 2-6 znaków alfabetycznych).
źródło
/D
flagę, a zacytowałeś ją pojedynczymi cudzysłowami, a także użyłeś ukośników do rozgraniczenia wzoru? To nie jest Perl i nie może być PCRE. Czy to zatem PHP? Sądzę, że są to jedyne trzy, które pozwalają na rekurencję(?1)
.Dziwne, że „nie możesz” pozwolić na 4 znaki TLD. Jesteś zakazu ludzi z .info i .name , a długość ograniczenie przystanek .travel i .museum , ale tak, są one mniej powszechne niż 2 znaki TLD i 3 znaki TLD.
Powinieneś także dopuścić duże litery. Systemy poczty elektronicznej znormalizują część lokalną i część domeny.
W przypadku wyrażenia regularnego części domeny nazwa domeny nie może zaczynać się od „-” i nie może kończyć się na „-”. Dash może pozostać tylko pomiędzy.
Jeśli korzystałeś z biblioteki PEAR, sprawdź jej funkcję poczty (nie pamiętam dokładnej nazwy / biblioteki). Możesz zweryfikować adres e-mail, wywołując jedną funkcję, a on sprawdza adres e-mail zgodnie z definicją w RFC822.
źródło
źródło