Learn Regex: A Beginner's Guide
Tässä oppaassa opit regexin eli säännöllisen lausekkeen syntaksin. Lopulta osaat soveltaa regex-ratkaisuja useimmissa skenaarioissa, jotka vaativat sitä web-kehitystyössäsi.
Säännöllisillä lausekkeilla on monia käyttötapauksia, joita ovat muun muassa:
- lomakkeen syötteen validointi
- verkkokaavinta
- haku ja korvaaminen
- tietojen suodattaminen massiivisista tekstitiedostoista, kuten lokitiedostoista
Säännölliset lausekkeet tai regexit eli regexit, jollaiseksi niitä kutsutaan yleisesti, näyttävät monimutkaisilta ja pelottavilta uusille käyttäjille. Katso tätä esimerkkiä:
/^+@+(?:\.+)*$/
Se näyttää vain sekavalta tekstiltä. Mutta älä masennu, hulluuden takana on metodi.
Credit: xkcd
Näytän sinulle, miten hallitset säännölliset lausekkeet hetkessä. Selvitetään ensin tässä oppaassa käytettyä terminologiaa:
- kuvio: säännöllisen lausekkeen kuvio
- merkkijono: testijono, jota käytetään sovittamaan kuvio
- numero: 0-9
- kirjain: a-z, A-Z
- symboli: !$%^&*()_+|~-=`{}:”;'<>?,./
- välilyönti: yksittäinen valkoinen välilyönti, tabulaattori
- merkki: viittaa kirjaimeen, numeroon tai symboliin
Basics
Oppiaksesi regexin nopeasti tämän oppaan avulla vieraile osoitteessa Regex101, jossa voit laatia regex-kuvioita ja testata niitä antamiasi merkkijonoja (tekstiä) vastaan.
Kun avaat sivuston, sinun on valittava JavaScript-maku, sillä sitä käytämme tässä oppaassa. (Regexin syntaksi on enimmäkseen sama kaikilla kielillä, mutta joitakin pieniä eroja on.)
Seuraavaksi sinun on poistettava Regex101:n global
– ja multi line
-liput käytöstä. Käsittelemme niitä seuraavassa osiossa. Nyt tarkastelemme yksinkertaisinta säännöllistä lauseketta, jonka voimme rakentaa. Syötä seuraava:
- regex-syöttökenttä: kissa
- testijono: rotta lepakko kissa istui lihava kissat syövät tat kissa matto KATTI
Huomaa, että säännönmukaiset lausekkeet alkavat ja päättyvät JavaScriptissä muotoon /
. Jos kirjoittaisit säännöllisen lausekkeen JavaScript-koodiin, se näyttäisi tältä: /cat/
ilman lainausmerkkejä. Yllä olevassa tilassa säännöllinen lauseke vastaa merkkijonoa ”kissa”. Kuten yllä olevasta kuvasta näkyy, on kuitenkin useita ”kissa”-merkkijonoja, joita ei soviteta. Seuraavassa osiossa tarkastelemme, miksi.
Globaalit ja isot ja pienet kirjaimet huomioimattomat regex-merkit
Oletusarvoisesti regex-kuvio palauttaa vain ensimmäisen löytämänsä osuman. Jos haluat palauttaa muitakin osumia, sinun on otettava käyttöön globaali lippu, jota merkitään g
. Regex-kuviot ovat myös oletusarvoisesti isojen ja pienten kirjainten suhteen herkkiä. Voit kumota tämän käyttäytymisen ottamalla käyttöön epäherkän lipun, jota merkitään i
. Päivitetty regex-kuvio on nyt täysin ilmaistu muodossa /cat/gi
. Kuten alla näkyy, kaikki ”cat”-merkkijonot on täsmäytetty, myös se, jolla on erilainen isokirjain.
Character Sets
Edellisessä esimerkissä opimme suorittamaan täsmällisiä isojen ja pienten kirjainten välisiä täsmäyksiä. Entäpä jos haluaisimme löytää vastaukset ”bat”, ”cat” ja ”fat”. Voimme tehdä tämän käyttämällä merkkijoukkoja, jotka merkitään . Periaatteessa annat useita merkkejä, jotka haluat sovittaa yhteen. Esimerkiksi at
vastaa useita merkkijonoja seuraavasti:
Merkkijoukot toimivat myös numeroiden kanssa.
Ranges
Asettakaamme, että haluamme vastata kaikkiin sanoihin, jotka päättyvät at
. Voisimme antaa koko aakkoston merkkijoukon sisällä, mutta se olisi työlästä. Ratkaisu on käyttää tällaisia alueita at
:
Tässä on koko testattava merkkijono: rat bat cat sat fat cats eat tat cat dog mat CAT
.
Kuten näet, kaikki sanat täsmäävät odotetusti. Olen lisännyt sanan dog
vain heittääkseni virheellisen osuman. Seuraavassa on muita tapoja käyttää alueita:
-
Osittainen alue: valinnat, kuten
tai
.
-
Kokoalue:
.
-
Numeroalue:
.
-
Symbolialue: esimerkiksi
.
-
Sekoitettu alue: esimerkiksi
sisältää kaikki numerot, pienet ja isot kirjaimet. Huomaa, että alue määrittää vain useita vaihtoehtoja yhdelle merkille kuviossa.
Ymmärtääksesi tarkemmin, miten alue määritetään, on parasta tarkastella koko ASCII-taulukkoa, jotta näet, miten merkit on järjestetty.
Merkkien toistaminen
Esitettäköön, että haluaisit sovittaa yhteen kaikki kolmikirjaimiset sanat. Tekisit sen luultavasti näin:
Tämä vastaisi kaikkia kolmikirjaimisia sanoja. Mutta entä jos haluat löytää viiden tai kahdeksan merkin pituisen sanan. Edellä mainittu menetelmä on työläs. On parempi tapa ilmaista tällainen kuvio käyttämällä {}
-juoksevien sulkujen merkintätapaa. Sinun tarvitsee vain määrittää toistuvien merkkien määrä. Tässä esimerkkejä:
-
a{5}
vastaa sanaa ”aaaaa”. -
n{3}
vastaa sanaa ”nnn”. -
{4}
vastaa mitä tahansa nelikirjaimista sanaa, kuten ”ovi”, ”huone” tai ”kirja”. -
{6,}
vastaa mitä tahansa sanaa, jossa on kuusi tai enemmän kirjaimia. -
{8,11}
vastaa mitä tahansa sanaa, jossa on kahdeksasta 11 kirjaimeen. Perussalasanan vahvistus voidaan tehdä tällä tavalla. -
{11}
vastaa 11-numeroista numeroa. Kansainvälisen puhelimen perusvalidointi voidaan tehdä tällä tavalla.
Metamerkit
Metamerkkien avulla voit kirjoittaa säännöllisen lausekkeen kuvioita, jotka ovat vieläkin tiiviimpiä. Käydään ne läpi yksi kerrallaan:
-
\d
vastaa mitä tahansa numeroa, joka on sama kuin -
\w
vastaa mitä tahansa kirjainta, numeroa ja alleviivausmerkkiä -
\s
vastaa välilyönti-merkkiä – ts, välilyönti tai tabulaattori -
\t
täsmää vain tabulaattorimerkin kanssa
Tähän mennessä oppimamme perusteella voimme kirjoittaa säännöllisiä lausekkeita seuraavasti:
-
\w{5}
vastaa mitä tahansa viiden kirjaimen sanaa tai viisinumeroista numeroa -
\d{11}
vastaa 11-numeroista numeroa, kuten puhelinnumeroa
Erikoismerkit
Erikoismerkit vievät meidät askeleen pidemmälle edistyneempien säännöllisten lausekkeiden kirjoittamisessa:
-
+
: Yksi tai useampi kvantifikaattori (edeltävän merkin on oltava olemassa, ja se voi olla valinnaisesti päällekkäinen). Esimerkiksi lausekec+at
vastaa lausekkeita ”cat”, ”ccat” ja ”ccccccccccat”. Voit toistaa edeltävän merkin niin monta kertaa kuin haluat, ja saat silti osuman. -
?
: Nolla tai yksi kvantifikaattori (edeltävä merkki on valinnainen). Esimerkiksi lausekec?at
vastaa vain ”cat” tai ”at”. -
*
: Nolla tai useampi kvantifikaattori (edeltävä merkki on valinnainen, ja se voi olla valinnaisesti päällekkäinen). Esimerkiksi lausekec*at
vastaa sanoja ”at”, ”cat” ja ”ccccccat”. Se on kuin yhdistelmä+
ja?
. -
\
: Tätä ”pakomerkkiä” käytetään, kun halutaan käyttää erikoismerkkiä kirjaimellisesti. Esimerkiksic\*
vastaa täsmälleen ”c*” eikä ”ccccccccc”. -
: tätä ”negate”-merkintää käytetään osoittamaan merkkiä, jota ei pidä sovittaa yhteen jonkin alueen sisällä. Esimerkiksi lauseke
bld
ei sovita ”bald” tai ”bbld”, koska toisena olevat kirjaimet a-c ovat negatiivisia. Kuvio vastaa kuitenkin sanoja ”beld”, ”bild”, ”bold” ja niin edelleen. -
.
: Tämä ”do”-merkintä vastaa mitä tahansa numeroa, kirjainta tai symbolia paitsi rivinvaihtoa. Esimerkiksi.{8}
vastaa kahdeksanmerkkistä salasanaa, joka koostuu kirjaimista, numeroista ja symboleista. esimerkiksi ”salasana” ja ”P@ssw0rd” sopivat molemmat yhteen.
Mitä tähän mennessä olemme oppineet, voimme luoda mielenkiintoisia erilaisia kompakteja mutta tehokkaita säännöllisiä lausekkeita. Esimerkiksi:
-
.+
vastaa yhtä tai rajoittamatonta määrää merkkejä. Esimerkiksi ”c” , ”cc” ja ”bcd#.670” täsmäävät kaikki. -
+
täsmää kaikkiin pienillä kirjaimilla kirjoitettuihin sanoihin niiden pituudesta riippumatta, kunhan ne sisältävät vähintään yhden kirjaimen. Esimerkiksi ”kirja” ja ”kokoushuone” täsmäävät molemmat.
Ryhmät
Kaikki äsken mainitsemamme erikoismerkit vaikuttavat vain yhteen merkkiin tai aluejoukkoon. Entä jos haluaisimme vaikutuksen kohdistuvan lausekkeen osaan? Voimme tehdä tämän luomalla ryhmiä käyttämällä pyöreitä hakasulkeita – ()
. Esimerkiksi kuvio book(.com)?
vastaa sekä ”book” että ”book.com”, koska olemme tehneet ”.com”-osasta valinnaisen.
Tässä on monimutkaisempi esimerkki, jota käytettäisiin realistisessa skenaariossa, kuten sähköpostin validoinnissa:
- kuvio:
@\w+\.\w{2,3}(\.\w{2,3})?
- testijono:
abc.com abc@mail @mail.com @mail.co.ke
Vaihtoehtoiset merkit
Regexissä voimme määrittää vaihtoehtoisia merkkejä käyttämällä ”putkisymbolia” – |
. Tämä eroaa aiemmin esittelemistämme erikoismerkeistä, sillä se vaikuttaa kaikkiin merkkeihin putkisymbolin kummallakin puolella. Esimerkiksi kuvio sat|sit
vastaa sekä ”sat”- että ”sit”-merkkijonoja. Voimme kirjoittaa kuvion uudelleen muotoon s(a|i)t
, jolloin se vastaa samoja merkkijonoja.
Yllä oleva kuvio voidaan ilmaista muotoon s(a|i)t
käyttämällä ()
-sulkeita.
Aloittavat ja lopettavat kuviot
Olet ehkä huomannut, että jotkin positiiviset täsmäämiset ovat osittaisen täsmäytyksen tulosta. Jos esimerkiksi kirjoitin kuvion, joka vastaa merkkijonoa ”boo”, myös merkkijono ”book” saa positiivisen vastaavuuden, vaikka se ei olekaan tarkka vastaavuus. Tämän korjaamiseksi käytämme seuraavia merkintöjä:
-
^
: sijoitettu alkuun, tämä merkki sopii kuvioon merkkijonon alussa. -
$
: sijoitettu loppuun, tämä merkki sopii kuvioon merkkijonon lopussa.
Korjataksemme yllä olevan tilanteen voimme kirjoittaa kuvion muodossa boo$
. Näin varmistetaan, että kolme viimeistä merkkiä täsmäävät kuvioon. On kuitenkin yksi ongelma, jota emme ole vielä ottaneet huomioon, kuten seuraava kuva osoittaa:
Merkkijono ”sboo” saa osuman, koska se täyttää edelleen nykyiset kuvion täsmäytysvaatimukset. Korjataksemme tämän voimme päivittää kuvion seuraavasti: ^boo$
. Tämä vastaa tiukasti sanaa ”boo”. Jos käytät molempia, molemmat säännöt pannaan täytäntöön. Esimerkiksi ^{5}$
vastaa tiukasti viisikirjaimista sanaa. Jos merkkijonossa on enemmän kuin viisi kirjainta, kuvio ei täsmää.
Regex JavaScriptissä
// Example 1const regex1=/a-z/ig//Example 2const regex2= new RegExp(//, 'ig')
Jos koneellesi on asennettu Node.js, avaa terminaali ja suorita komento node
käynnistääksesi Node.js:n komentotulkin. Suorita seuraavaksi seuraavasti:
Leikkikää vapaasti lisää regex-kuvioilla. Kun olet valmis, lopeta komennolla .exit
komentotulkki.
Real World Example: Sähköpostin validointi
Käsittelemme tämän oppaan lopuksi erästä regexin suosittua käyttötapaa, sähköpostin validointia. (Haluamme esimerkiksi tarkistaa, että sähköpostiosoite, jonka käyttäjä on syöttänyt lomakkeeseen, on kelvollinen sähköpostiosoite.)
Tämä aihe on monimutkaisempi kuin luulisi. Sähköpostiosoitteen syntaksi on melko yksinkertainen: {name}@{domain}
. Teoriassa sähköpostiosoite voi sisältää rajoitetun määrän symboleja, kuten #-@&%.
jne. Näiden symbolien sijoittelulla on kuitenkin merkitystä. Sähköpostipalvelimilla on myös erilaisia sääntöjä symbolien käytöstä. Jotkin palvelimet käsittelevät esimerkiksi symbolia +
virheellisenä. Toisissa sähköpostipalvelimissa symbolia käytetään sähköpostin aliosoitteisiin.
Haasteena testataksesi tietämystäsi yritä muodostaa säännöllisen lausekkeen kuvio, joka sopii vain alla merkittyihin kelvollisiin sähköpostiosoitteisiin:
# invalid emailabcabc.com# valid email [email protected]@[email protected]@[email protected]# invalid email [email protected]@[email protected]#[email protected]# valid email [email protected]@[email protected][email protected]# invalid domain [email protected]@mail#[email protected]@mail..com# valid domain [email protected]@[email protected]@[email protected]
Huomaa, että jotkin kelvollisiksi merkityt sähköpostiosoitteet voivat olla kelvottomia tietyissä organisaatioissa, kun taas jotkin kelvottomiksi merkityistä sähköpostiosoitteista voivat itse asiassa olla sallittuja toisissa organisaatioissa. Oli miten oli, on ensiarvoisen tärkeää oppia rakentamaan mukautettuja säännöllisiä lausekkeita organisaatioille, joille työskentelet, jotta voit vastata niiden tarpeisiin. Jos jäät jumiin, voit tarkastella seuraavia mahdollisia ratkaisuja. Huomaa, että mikään niistä ei anna 100-prosenttista vastaavuutta yllä oleviin kelvollisiin sähköpostin testijonoihin.
- Mahdollinen ratkaisu 1:
^\w*(\-\w)?(\.\w*)?@\w*(-\w*)?\.\w{2,3}(\.\w{2,3})?$
- Mahdollinen ratkaisu 2:
^((\.,;:\s@"]+(\.\.,;:\s@"]+)*)|(".+"))@((\{1,3}\.{1,3}\.{1,3}\.{1,3}])|((+\.)+{2,}))$
Yhteenveto
Toivottavasti olet nyt oppinut säännöllisten lausekkeiden perusteet. Emme ole käsitelleet kaikkia regex-ominaisuuksia tässä nopeassa aloittelijan oppaassa, mutta sinulla pitäisi olla tarpeeksi tietoa useimpien regex-ratkaisua vaativien ongelmien ratkaisemiseen. Jos haluat oppia lisää, lue oppaamme parhaista käytännöistä regexin käytännön soveltamisessa reaalimaailman skenaarioissa.