Regular Expressions
Användbar Regex Showcase
Sök…
Matcha ett datum
Du bör komma ihåg att regex var utformat för att matcha ett datum (eller inte). Att säga att ett datum är giltigt är en mycket mer komplicerad kamp, eftersom det kommer att kräva mycket undantagshantering (se förhållanden för skottår ).
Låt oss börja med att matcha månaden (1 - 12) med en valfri ledande 0:
0?[1-9]|1[0-2]
För att matcha dagen, också med en ledande 0:
0?[1-9]|[12][0-9]|3[01]
Och för att matcha året (låt oss bara anta intervallet 1900 - 2999):
(?:19|20)[0-9]{2}
Separatorn kan vara ett mellanrum, en streck, en snedstreck, tom, etc. Lägg gärna till allt du känner kan användas som separator:
[-\\/ ]?
Nu sammanfogar du hela saken och får:
(0?[1-9]|1[0-2])[-\\/ ]?(0?[1-9]|[12][0-9]|3[01])[-/ ]?(?:19|20)[0-9]{2} // MMDDYYYY
(0?[1-9]|[12][0-9]|3[01])[-\\/ ]?(0?[1-9]|1[0-2])[-/ ]?(?:19|20)[0-9]{2} // DDMMYYYY
(?:19|20)[0-9]{2}[-\\/ ]?(0?[1-9]|1[0-2])[-/ ]?(0?[1-9]|[12][0-9]|3[01]) // YYYYMMDD
Om du vill vara lite mer pedantisk kan du använda en bakreferens för att vara säker på att de två separatorerna kommer att vara desamma:
(0?[1-9]|1[0-2])([-\\/ ]?)(0?[1-9]|[12][0-9]|3[01])\2(?:19|20)[0-9]{2} // MMDDYYYY
^ refer to [-/ ]
(0?[1-9]|[12][0-9]|3[01])([-\\/ ]?)(0?[1-9]|1[0-2])\2(?:19|20)[0-9]{2} // DDMMYYYY
(?:19|20)[0-9]{2}([-\\/ ]?)(0?[1-9]|1[0-2])\2(0?[1-9]|[12][0-9]|3[01]) // YYYYMMDD
Matcha en e-postadress
Att matcha en e-postadress i en sträng är en svår uppgift, eftersom specifikationen som definierar den, RFC2822 , är komplex och gör det svårt att implementera som en regex. För mer information varför det inte är bra att matcha ett e-postmeddelande med en regex, se antipattern-exemplet när du inte ska använda en regex: för att matcha e-postmeddelanden . Det bästa rådet att notera från den sidan är att använda ett kamratgranskat och allmänt bibliotek på ditt favoritspråk för att implementera detta.
Validera ett e-postadressformat
När du snabbt måste validera en post för att se till att den ser ut som en e-post är det bästa alternativet att hålla det enkelt:
^\S{1,}@\S{2,}\.\S{2,}$
Det regexet kommer att kontrollera att e-postadressen är en sekvens med icke-mellanslag separerad av tecken med längd större än en, följt av en @
, följt av två sekvenser av icke-mellanslagstecken med längd två eller fler separerade av a .
. Det är inte perfekt och kan validera ogiltiga adresser (enligt formatet), men viktigast av allt är att den inte ogiltigför giltiga adresser.
Kontrollera att adressen finns
Det enda pålitliga sättet att kontrollera att ett e-postmeddelande är giltigt är att kontrollera om det finns. Det fanns tidigare VRFY
SMTP-kommandot som har utformats för det ändamålet, men tyvärr, efter att ha missbrukats av spammare är det nu inte tillgängligt längre .
Så det enda sättet du har kvar för att kontrollera att e-postmeddelandet är giltigt och existerar är att faktiskt skicka ett e-postmeddelande till den adressen.
Stora Regex-alternativ
Det är dock inte omöjligt att validera ett adressmeddelande med en regex. De enda frågorna är att ju närmare specifikationen dessa regexer kommer att vara, desto större blir de och som en följd av detta är de omöjligt svåra att läsa och underhålla. Nedan hittar du exempel på en så exaktare regex som används i vissa bibliotek.
⚠️ Följande regex ges för dokumentation och inlärningsändamål, kopia klistra in dem i din kod är en dålig idé. Använd istället det biblioteket direkt, så att du kan lita på uppströms kod och peer-utvecklare för att hålla din e-postpersonskodning uppdaterad och underhållen.
Perl Adress-matchningsmodul
De bästa exemplen på sådant regex är standardbibliotek på vissa språk. Till exempel finns det en från RFC::RFC822::Address
i Perl-biblioteket som försöker vara så exakt som möjligt enligt RFC. För din nyfikenhet kan du hitta en version av det regexet på denna URL , som har genererats från grammatiken, och om du frestas att kopiera klistra in det, här är citat från regex 'författare:
" Jag behåller inte det reguljära uttrycket [länkad. Det kan finnas buggar i det som redan har fixats i Perl-modulen. "
.Nätadressmatchningsmodul
En annan, kortare variant är den som används av .Net-standardbiblioteket i modulen EmailAddressAttribute
:
^((([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+(\.([a-z]|\d|[!#\$%&'\*\+\-\/=\?\^_`{\|}~]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])+)*)|((\x22)((((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(([\x01-\x08\x0b\x0c\x0e-\x1f\x7f]|\x21|[\x23-\x5b]|[\x5d-\x7e]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(\\([\x01-\x09\x0b\x0c\x0d-\x7f]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF]))))*(((\x20|\x09)*(\x0d\x0a))?(\x20|\x09)+)?(\x22)))@((([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|\d|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.)+(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])|(([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])([a-z]|\d|-|\.|_|~|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])*([a-z]|[\u00A0-\uD7FF\uF900-\uFDCF\uFDF0-\uFFEF])))\.?$
Men även om det är kortare är det fortfarande för stort för att vara läsbart och lätt att underhålla.
Ruby Address-matchningsmodul
I rubin används en komposition av regex i rfc822-modulen för att matcha en adress. Det här är en snygg idé, eftersom det skulle vara lättare att fastställa regex-delen för att ändra och fixa om buggar hittas.
Python-adressmatchningsmodul
Som ett motexempel använder inte Python- e-postpartringsmodulen ett regex utan implementerar det istället med en parser.
Matcha ett telefonnummer
Så här matchar du ett prefixkod (a +
eller (00), sedan ett nummer från 1 till 1939, med ett valfritt utrymme):
Detta letar inte efter ett giltigt prefix utan något som kan vara ett prefix. Se hela listan med prefix
(?:00|\+)?[0-9]{4}
Sedan hela telefonnumret är högst 15 kan vi leta efter upp till 14 siffror:
Minst 1 siffra spenderas för prefixet
[0-9]{1,14}
Siffrorna kan innehålla mellanslag, prickar eller streck och kan grupperas med 2 eller 3.
(?:[ .-][0-9]{3}){1,5}
Med det valfria prefixet:
(?:(?:00|\+)?[0-9]{4})?(?:[ .-][0-9]{3}){1,5}
Om du vill matcha ett specifikt landsformat kan du använda denna sökfråga och lägga till landet, frågan har verkligen redan ställts.
Matcha en IP-adress
IPv4
För att matcha IPv4-adressformat måste du kontrollera om siffrorna [0-9]{1,3}
tre gånger {3}
separerade med perioder \.
och slutar med ett annat nummer.
^(?:[0-9]{1,3}\.){3}[0-9]{1,3}$
Detta reguljära uttryck är för enkelt - om du vill att det ska vara korrekt måste du kontrollera att siffrorna är mellan 0
och 255
, med regexet ovan accepterar 444
i valfri position. Du vill kontrollera om 250-255 med 25[0-5]
, eller något annat 200 värde 2[0-4][0-9]
, eller 100 värde eller mindre med [01]?[0-9][0-9]
. Du vill kontrollera att den följs av en period \.
tre gånger {3}
och sedan en gång utan en period.
^(?:(?: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]?)$
IPv6
IPv6-adresser i form av 8 16-bitars hex ord avgränsade med kolon ( :
) karaktär. I det här fallet ser vi efter 7 ord följt av kolon, följt av ett som inte är det. Om ett ord har ledande nollor kan de trunkerade, vilket innebär att varje ord kan innehålla mellan 1 och 4 hexadecimala siffror.
^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$
Detta är dock otillräckligt. Eftersom IPv6-adresser kan bli ganska "ordliga", anger standarden att endast noll-orden kan ersättas av ::
. Detta får bara göras en gång på en adress (för någonstans mellan 1 och 7 ord i följd), eftersom det annars skulle vara obestämd. Detta ger ett antal (ganska otäcka) variationer:
^::(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}$
^[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}$
^[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}$
^(?:[0-9a-fA-F]{1,4}:){0,2}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,3}[0-9a-fA-F]{1,4}$
^(?:[0-9a-fA-F]{1,4}:){0,3}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,2}[0-9a-fA-F]{1,4}$
^(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:)?[0-9a-fA-F]{1,4}$
^(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}::[0-9a-fA-F]{1,4}$
^(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}::$
Genom att sätta samman allt (med växel) ger du:
^(?:[0-9a-fA-F]{1,4}:){7}[0-9a-fA-F]{1,4}$|
^::(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}$|
^[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}$|
^[0-9a-fA-F]{1,4}:[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}$|
^(?:[0-9a-fA-F]{1,4}:){0,2}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,3}[0-9a-fA-F]{1,4}$|
^(?:[0-9a-fA-F]{1,4}:){0,3}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:){0,2}[0-9a-fA-F]{1,4}$|
^(?:[0-9a-fA-F]{1,4}:){0,4}[0-9a-fA-F]{1,4}::(?:[0-9a-fA-F]{1,4}:)?[0-9a-fA-F]{1,4}$|
^(?:[0-9a-fA-F]{1,4}:){0,5}[0-9a-fA-F]{1,4}::[0-9a-fA-F]{1,4}$|
^(?:[0-9a-fA-F]{1,4}:){0,6}[0-9a-fA-F]{1,4}::$
Var noga med att skriva ut det i multiline-läge och med en hög med kommentarer så vem som oundvikligen har i uppgift att ta reda på vad detta betyder kommer inte efter dig med ett trubbigt föremål.
Validera en sträng på 12 timmar och 24 timmar
För ett 12-timmarsformat kan man använda:
^(?:0?[0-9]|1[0-2])[-:][0-5][0-9]\s*[ap]m$
Var
-
(?:0?[0-9]|1[0-2])
är timmen -
[-:]
är separatorn, som kan justeras för att passa ditt behov -
[0-5][0-9]
är minuten -
\s*[ap]m
följde valfritt antal vitrumstecken och äram
ellerpm
Om du behöver sekunderna:
^(?:0?[0-9]|1[0-2])[-:][0-5][0-9][-:][0-5][0-9]\s*[ap]m$
För ett 24 timmarsformat:
^(?:[01][0-9]|2[0-3])[-:h][0-5][0-9]$
Var:
-
(?:[01][0-9]|2[0-3])
är timmen -
[-:h]
separatorn, som kan justeras för att passa ditt behov -
[0-5][0-9]
är minuten
Med sekunderna:
^(?:[01][0-9]|2[0-3])[-:h][0-5][0-9][-:m][0-5][0-9]$
Där [-:m]
är en andra separator, ersätter h
i timmar med en m
i minuter, och [0-5][0-9]
är den andra.
Matcha Storbritanniens postnummer
Regex för att matcha postnummer i Storbritannien
Formatet är enligt följande, där A anger en bokstav och 9 en siffra:
Formatera | Rapportering | Exempel |
---|---|---|
Cell | Cell | |
AA9A 9AA | WC-postnummerområde; EC1 – EC4, NW1W, SE1P, SW1 | EC1A 1BB |
A9A 9AA | E1W, N1C, N1P | W1A 0AX |
A9 9AA, A99 9AA | B, E, G, L, M, N, S, W | M1 1AE, B33 8TH |
AA9 9AA, AA99 9AA | Alla andra postnummer | CR2 6XH, DN55 1PT |
(GIR 0AA)|((([A-Z-[QVX]][0-9][0-9]?)|(([A-Z-[QVX]][A-Z-[IJZ]][0-9][0-9]?)|(([A-Z-[QVX]][0-9][A-HJKPSTUW])|([A-Z-[QVX]][A-Z-[IJZ]][0-9][ABEHMNPRVWXY])))) [0-9][A-Z-[CIKMOV]]{2})
Där första delen:
(GIR 0AA)|((([A-Z-[QVX]][0-9][0-9]?)|(([A-Z-[QVX]][A-Z-[IJZ]][0-9][0-9]?)|(([A-Z-[QVX]][0-9][A-HJKPSTUW])|([A-Z-[QVX]][A-Z-[IJZ]][0-9][ABEHMNPRVWXY]))))
Andra:
[0-9][A-Z-[CIKMOV]]{2})