Ověřte e-mailové adresy pomocí regulárních výrazů v JavaScriptu

Úvod

Pro webové vývojáře má zásadní význam ověřování uživatelských vstupů v různých typech formulářů. Protože to je výchozí bod odesílání dat mezi klientem a serverem, musíte se ujistit, že vše začíná tou správnou nohou – abyste neskončili s robustní validací na serveru end, což je často větší problém než to udělat na front-endu.

Vstup může být navíc škodlivý – v takovém případě musíte vzít v úvahu také zabezpečení. Je lepší se tomu úplně vyhnout ověřením vstupu na front-endu.

Regulární výrazy v JavaScriptu

Pro každého, kdo neovládá regulární výrazy nebo kdo má pocit, že potřebuje rychlé připomenutí, tady je!

Prostřednictvím metaznaků, kvantifikátorů, skupin a escape znaků – můžete vyjadřovat prostě jakýkoli vzor. Tento výraz například označuje sekvenci znaků, která obsahuje jakékoli platné písmeno mezi A–Z (malá i velká) nebo číslic v libovolné kombinaci:

^([A-Za-z]|[0-9])+$

To je také známé jako kontrola, zda je sekvence alfanumerická .

Po zbytek průvodce budeme předpokládat, že regulární výrazy trochu znáte.

Shoda e-mailových formátů v JavaScriptu s regulárními výrazy

V první řadě regulární výraz, který odpovídá všem možným platným e-mailovým adresám, neexistuje . Avšak ten, který odpovídá 99,9 % , dělá. Při ověřování e-mailů nebo skutečně jakéhokoli vstupu je dobrým postupem, který může víceméně zaručit, že uživatel bude odpovídat regulárnímu výrazu, omezit vstup uživatele předem.

Například povinné používání gmail.com nebo yahoo.com a přímé odmítnutí nepodporovaných poskytovatelů (ačkoli narazíte na problém škálovatelnosti a udržení aktuálního stavu s tímto přístupem).

Nabízí se další otázka:

Je to překvapivě volná definice, jak zanedlouho uvidíme – a můžete na to jít jednoduše nebo robustně. Probereme nejobecnější regulární výrazy pro ověřování e-mailů a také ty, které jsou v průvodci konkrétnější.

Než se pustíme do kódu, podívejme se na náhled e-mailových formátů, kterými se budeme zabývat:

  • Obecný formát - (něco)@(nějaká_doména).(nějaká_doména_nejvyšší úrovně)
  • Konkrétní hostitelé nebo domény - odkazující na konkrétní typ domény nebo domény nejvyšší úrovně
  • RFC 5322 - Formát internetových zpráv, pokrývající 99,9 % e-mailových adres

Obecný e-mailový formát Regulární výraz

Po mnoha pokusech o ověření pomocí robustních regulárních výrazů se mnoho inženýrů vrátí ke starému dobrému „obecnému“ formátu, který funguje většinu času. O tom, zda je to dobrá věc nebo ne, lze diskutovat.

Co obnáší e-mailová adresa? Musí mít @ symbol, stejně jako některé řetězec před ním a některé řetězec to pokračuje. Druhý řetězec navíc musí obsahovat tečku, která má za sebou další 2–3 znaky.

Na závěr je to hrubý náčrt:

(randomString)@(randomString2).(2-3 characters)

Vyplývá to z obecné intuice těchto e-mailů, které jsou platné:

[email protected]
[email protected]
[email protected]

S ohledem na to, abychom obecně ověřili e-mailovou adresu v JavaScriptu pomocí regulárních výrazů, přeložíme hrubý náčrt do RegExp :

let regex = new RegExp('[a-z0-9][email protected][a-z]+\.[a-z]{2,3}');

let testEmails = ["notanemail.com", "[email protected]", "[email protected]", "[email protected]"];

testEmails.forEach((address) => {
    console.log(regex.test(address))
});

První řetězec může obsahovat libovolné malé alfanumerické znaky - john.doe.1 , workingemail , atd.

Výsledkem je:

false
true
true
false

Bude to vždy fungovat? Ne. Budou nějaké špatně formátované e-maily, které procházejí. Pomocí tohoto regulárního výrazu také nelze provádět detekci spamu, takže e-mailová adresa, která intuitivně vypadá jako spam, tento výraz v pohodě projde:

console.log(regex.test("[email protected]")); // true

Zdarma e-kniha:Git Essentials

Prohlédněte si našeho praktického průvodce učením Git s osvědčenými postupy, průmyslově uznávanými standardy a přiloženým cheat sheetem. Přestaňte používat příkazy Google Git a skutečně se naučte to!

Ačkoli i ty nejrobustnější a nejsložitější výrazy pro ověření e-mailových adres v tomto selhávají – jsou tu k ověření formuláře , nikoli zda e-mail existuje.

Konkrétní e-mailové adresy

Snížení míry nejistoty pomáhá. Čím méně nejistoty, tím méně omezení vás potřeba vnutit pomocí výrazu. Díky tomu je ověřování konkrétních e-mailových adres přesnější pomocí stejných obecných formátů, jaké jsme právě viděli – nemusíte pokrývat tolik okrajových případů.

Podívejme se na některé obecné případy týkající se domény a domény nejvyšší úrovně.

Ověření domény e-mailové adresy pomocí JavaScriptu

Řekněme, že pracujete ve společnosti Stack Abuse . Všichni zaměstnanci mají e-mail končící @stackabuse.com a uživatelský řetězec se mění. Hrubý náčrt by vypadal takto:

(randomString)@stackabuse.com

Díky tomu je náš úkol mnohem jednodušší, protože některé proměnné, jako je název domény a typ organizace, jsou nyní opraveny. Tyto dvě jsou typické proměnné způsobující problémy, protože názvy domén se mohou divoce lišit .

Ověření e-mailové adresy příslušející konkrétní doméně se tak stává snadným úkolem pomocí RegExp třída:

let regex = new RegExp('[a-z0-9][email protected]');

let testEmails = ["notanemail.com", "[email protected]", "[email protected]"];

testEmails.forEach((address) => {
    console.log(regex.test(address))
});

Výsledkem je:

false
true
false

Pomocí tohoto přístupu můžete změnit libovolný doslovný řetězec tak, aby odpovídal vašim potřebám. Jako vždy lze první část regulárního výrazu změnit tak, aby odpovídala velkým písmenům, včetně speciálních znaků, jako je + nebo _ , atd.

Ověřování e-mailových adres nejvyšší úrovně v JavaScriptu

Tento případ je velmi podobný předchozímu, až na to, že omezíme poslední dva nebo tři znaky e-mailu.
Může to být doslova kterýkoli z:.com, .org, .edu, . eu, .us , atd. Přiřazujeme pouze e-maily obsahující .edu protože to nikdy není pouze tato doména nejvyšší úrovně, ale místo toho něco jako [email protected] .

let regex = new RegExp('[a-z0-9][email protected][a-z]+\.edu\.[a-z]{2,3}');

let testEmails = ["notanemail.com", "[email protected]", "[email protected]"];

testEmails.forEach((address) => {
    console.log(regex.test(address))
});

Neplatný e-mail i platný e-mail selžou – protože neobsahují edu v jejich doméně nejvyšší úrovně však vytvořená adresa Yale funguje:

false
false
true

Formát RFC 5322

Formát RFC 5322 je Internet Message Format (klasický formát e-mailové zprávy). RFC 5322 pouze diktuje, co by mělo být povoleno – není to samotný výraz.

Existuje několik výrazů, které implementují stanovená pravidla a ta mohou být pěkně složitá.

Zkrácená verze je:

let regex = new RegExp("([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|\"\(\[\]!#-[^-~ \t]|(\\[\t -~]))+\")@([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|\[[\t -Z^-~]*])");

Zatímco rozšířená verze, která pokrývá další edge-case, je:

(?:[a-z0-9!#$%&'*+/=?^_`{|}~-]+(?:\.[a-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])+)\])

Těmto výrazům není příliš snadné porozumět, pokud je nerozdělíte do skupin a nestrávíte nějaký čas jejich čtením. Jednodušší způsob je si to představit:

*Obrázek a tvrzení o přesnosti jsou laskavým svolením společnosti EmailRegex.com .

Jak již bylo řečeno, pojďme místo toho použít tento výraz k ověření několika adres:

let regex = new RegExp("([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|\"\(\[\]!#-[^-~ \t]|(\\[\t -~]))+\")@([!#-'*+/-9=?A-Z^-~-]+(\.[!#-'*+/-9=?A-Z^-~-]+)*|\[[\t -Z^-~]*])");

let testEmails = ["notanemail.com", "[email protected]", "[email protected]"];

testEmails.forEach((address) => {
    console.log(regex.test(address))
});

Výsledkem je:

false
true
true

Tento výraz můžete interaktivně testovat prostřednictvím krásného rozhraní na regex101.

Závěr

Závěrem lze říci, že skutečně neexistuje jediný „správný“ způsob, jak ověřit e-mailové adresy pomocí regulárních výrazů. Existuje však špatný způsob – pokud nepokryjete případy, které by neměly být správné.

Pro ty, kteří se chtějí ujistit, že doslova, téměř všechno je pokryta – použijte formát RFC 5322.