Vodič za bijeg znakova u Javi RegExps

1. Pregled

API regularnih izraza u Javi, java.util.regex široko se koristi za podudaranje uzoraka. Da biste otkrili više, možete slijediti ovaj članak.

U ovom ćemo se članku usredotočiti na izbjegavanje znakova s ​​regularnim izrazom i pokazati kako se to može učiniti na Javi.

2. Posebni RegExp znakovi

Prema dokumentaciji API-ja za regularne izraze Java, u regularnom izrazu postoji skup posebnih znakova koji su poznati i kao metaznakovi.

Kad želimo dopustiti likovima kakve jesu, umjesto da ih tumačimo s njihovim posebnim značenjima, moramo im pobjeći. Izbjegavanjem tih znakova prisiljavamo ih da se prema njima postupaju kao prema običnim znakovima kada se niz podudara s danim regularnim izrazom.

Metaznakovi koji nam obično trebaju da pobjegnemo na ovaj način su:

Pogledajmo jednostavan primjer koda u kojem se podudaraju ulazni podaci Niz s uzorkom izraženim u regularnom izrazu.

Ovaj test pokazuje da za zadani ulazni niz foof kad obrazac foo. (foo završava s točkom) podudara se, vraća vrijednost od pravi što ukazuje na to da je utakmica uspješna.

@Test javna praznina givenRegexWithDot_whenMatchingStr_thenMatches () {String strInput = "foof"; Niz strRegex = "foo."; assertEquals (true, strInput.matches (strRegex)); }

Možda se pitate zašto je podudaranje uspješno kada na ulazu nema znaka točke (.) Niz?

Odgovor je jednostavan. Točka (.) Je metaznak - ovdje je posebno značenje to što na njenom mjestu može biti 'bilo koji lik'. Stoga je jasno kako je meč utvrdio da je pronađeno podudaranje.

Recimo da ne želimo liječiti točkasti (.) Znak jedinstvenim značenjem. Umjesto toga, želimo da se to protumači kao točkasti znak. To znači da u prethodnom primjeru ne želimo dopustiti obrazac foo. imati podudarnost na ulazu Niz.

Kako bismo se nosili s ovakvom situacijom? Odgovor je: trebamo pobjeći od točkanog (.) znaka tako da se njegovo posebno značenje zanemari.

Istražimo ga detaljnije u sljedećem odjeljku.

3. Bijeg likova

Prema dokumentaciji Java API-ja za regularne izraze, postoje dva načina na koja možemo pobjeći od znakova koji imaju posebno značenje. Drugim riječima, prisiliti ih da se prema njima postupa kao prema običnim likovima.

Da vidimo što su:

  1. Prethodi metaznaku s kosom crtom (\)
  2. Priložite metaznak s \ Q i \ E

To samo znači da u primjeru koji smo ranije vidjeli, ako želimo pobjeći od točke točke, trebamo staviti znak kosa crta ispred znaka točke. Alternativno, točkasti znak možemo postaviti između \ Q i \ E.

3.1. Bijeg pomoću povratne crte

Ovo je jedna od tehnika koju možemo koristiti za bijeg od metaznaka u regularnom izrazu. Međutim, znamo da je znak s kosom crtom bijeg u Javi Niz doslovce također. Stoga trebamo udvostručiti znak s kosom crtom kada ga koristimo ispred bilo kojeg znaka (uključujući i sam znak \).

Stoga u našem primjeru moramo promijeniti regularni izraz kao što je prikazano u ovom testu:

@Test javna praznina givenRegexWithDotEsc_whenMatchingStr_thenNotMatching () {String strInput = "foof"; Niz strRegex = "foo \."; assertEquals (false, strInput.matches (strRegex)); }

Ovdje se izbjegava znak točkice, pa ga podudarnik jednostavno tretira kao točku i pokušava pronaći uzorak koji završava točkom (tj. foo.).

U ovom se slučaju vraća lažno budući da na ulazu nema podudaranja Niz za taj obrazac.

3.2. Bijeg pomoću \ Q & \ E-a

Alternativno, možemo koristiti \ Q i \ E da pobjegne od posebnog lika. \ Q označava da svi znakovi do \ E treba pobjeći i \ E znači da moramo završiti bijeg s kojim je započeto \ Q.

To samo znači da sve što je između \ Q i \ E bi se pobjeglo.

U ovdje prikazanom testu, podjela() od Niz class podudara se pomoću regularnog izraza koji mu je dan.

Naš je zahtjev podijeliti ulazni niz znakom pipe (|) u riječi. Stoga za to koristimo obrazac regularnog izraza.

Znak luke metaznak je koji treba izbjeći u regularnom izrazu.

Ovdje se bijeg vrši stavljanjem znaka cijevi između \ Q i \ E:

@Test javna praznina givenRegexWithPipeEscaped_whenSplitStr_thenSplits () \ E "; assertEquals (4, strInput.split (strRegex) .length); 

4. The Uzorak.citat (Niz S) Metoda

Metoda uzorka.citata (niza S) u java.util.regex.Pattern klasa pretvara zadani obrazac regularnog izraza Niz u doslovni obrazac Niz. To znači da su svi metaznakovi u inputu Niz tretiraju se kao obični likovi.

Korištenje ove metode bila bi prikladnija alternativa od korištenja \ Q & \ E dok obavija dano Niz sa njima.

Pogledajmo ovu metodu na djelu:

@Test javna praznina givenRegexWithPipeEscQuoteMeth_whenSplitStr_thenSplits () bar

U ovom brzom testu, Pattern.quote () metoda koristi se za bijeg od zadanog regularnog izraza i pretvaranje u Niz doslovno. Drugim riječima, izbjegava sve metakaraktere koji su prisutni u regularnom uzorku za nas. Radi sličan posao kao \ Q & \ E.

Znak cijevi izbjegnut je znakom Pattern.quote () metoda i podjela() tumači kao a Niz doslovni kojim dijeli ulaz.

Kao što vidimo, ovo je puno čišći pristup, a također programeri ne moraju pamtiti sve sekvence bijega.

To bismo trebali primijetiti Uzorak.citat zatvara cijeli blok jednim redoslijedom bijega. Ako bismo htjeli pojedinačno pobjeći od znakova, morali bismo koristiti algoritam zamjene tokena.

5. Dodatni primjeri

Pogledajmo kako zamjeni sve() metoda java.util.regex.Matcher djela.

Ako trebamo zamijeniti sve pojave određenog znaka Niz s drugom, ovu metodu možemo koristiti prenoseći joj regularni izraz.

Zamislite da imamo ulaz s više pojavljivanja znaka $ lik. Rezultat koji želimo dobiti isti je niz sa znakom $ znak zamijenjen £.

Ovaj test pokazuje kako obrazac $ donosi se bez izbjegavanja:

@Test javna praznina givenRegexWithDollar_whenReplacing_thenNotReplace () {String strInput = "Dao sam 50 dolara svom bratu." + "Kupio je slatkiše za 35 dolara. Sad mu je ostalo 15 dolara."; Niz strRegex = "$"; Niz strReplacement = "£"; String output = "Dao sam 50 funti bratu." + "Kupio je slatkiše za 35 funti. Sada mu je ostalo 15 funti."; Uzorak p = obrazac.compile (strRegex); Podudaranje m = p.matcher (strInput); assertThat (output, not (jednakTo (m.replaceAll (strReplacement))))); }

Test to tvrdi $ nije ispravno zamijenjen s £.

Ako izbjegnemo obrazac regularnog izraza, zamjena se događa ispravno i test prolazi kao što je prikazano u ovom isječku koda:

@Test javna praznina givenRegexWithDollarEsc_whenReplacing_thenReplace () {String strInput = "Dao sam 50 dolara svom bratu." + "Kupio je slatkiše za 35 dolara. Sad mu je ostalo 15 dolara."; Niz strRegex = "\ $"; Niz strReplacement = "£"; String output = "Dao sam 50 funti bratu." + "Kupio je slatkiše za 35 funti. Sada mu je ostalo 15 funti."; Uzorak p = obrazac.compile (strRegex); Podudaranje m = p.matcher (strInput); assertEquals (output, m.replaceAll (strReplacement)); }

Napomena \\$ ovdje, što čini trik bježeći od $ znak i uspješno podudaranje s uzorkom.

6. Zaključak

U ovom smo članku pogledali odbjegle znakove u regularnim izrazima na Javi.

Raspravljali smo zašto treba izbjegavati regularne izraze i različite načine na koje se to može postići.

Kao i uvijek, izvorni kod povezan s ovim člankom možete pronaći na GitHubu.