Programiranje

Regularni izrazi v Javi, 1. del: Ujemanje vzorcev in razred Pattern

Razredi znakov in različnih nizov Java ponujajo nizko stopnjo podpore za ujemanje vzorcev, vendar ta podpora običajno vodi do zapletene kode. Za enostavnejše in učinkovitejše kodiranje Java ponuja Regex API. Ta dvodelna vadnica vam pomaga začeti z regularnimi izrazi in API-jem Regex. Najprej bomo razpakirali tri močne razrede, ki prebivajo v java.util.regex paket, nato bomo raziskali Vzorec razreda in njegovih dovršenih konstrukcij za ujemanje vzorcev.

prenos Prenesite kodo Prenesite izvorno kodo, na primer programe v tej vadnici. Ustvaril Jeff Friesen za JavaWorld.

Kaj so regularni izrazi?

A vsakdanje izražanje, znan tudi kot a regularni izraz ali regularni izraz, je niz, katerega vzorec (template) opisuje niz nizov. Vzorec določa, kateri nizi pripadajo naboru. Vzorec je sestavljen iz dobesednih znakov in metaznaki, ki so znaki, ki imajo poseben pomen namesto dobesednega pomena.

Ujemanje vzorcev je postopek iskanja besedila za prepoznavanje tekmeali nizi, ki se ujemajo z vzorcem regularnega izraza. Java podpira ujemanje vzorcev prek API-ja Regex. API je sestavljen iz treh razredov -Vzorec, Matcher, in PatternSyntaxException- vsi se nahajajo v java.util.regex paket:

  • Vzorec predmeti, znani tudi kot vzorci, so sestavljeni regularni izrazi.
  • Matcher predmeti, oz tekme, so motorji, ki interpretirajo vzorce za iskanje zadetkov v zaporedja znakov (predmeti, katerih razredi izvajajo java.lang.CharSequence vmesnik in služijo kot besedilni viri).
  • PatternSyntaxException predmeti opisujejo nezakonite vzorce regularnih izrazov.

Java ponuja tudi podporo za ujemanje vzorcev z različnimi metodami v svojem java.lang.String razred. Na primer, logična ujemanja (String regex) vrne true samo če priklicni niz se natančno ujema regularni izrazje regularni izraz.

Priročne metode

V zakulisju, ujemanja () in VrvicaDruge metode udobja, usmerjene v regularne izraze, so uporabljene v smislu API-ja Regex.

RegexDemo

Ustvaril sem RegexDemo aplikacija za prikaz regularnih izrazov Java in različnih metod, ki se nahajajo v Vzorec, Matcher, in PatternSyntaxException razredih. Tu je izvorna koda za predstavitev:

Seznam 1. Prikaz regularnih izrazov

uvoz java.util.regex.Matcher; uvoz java.util.regex.Pattern; uvoz java.util.regex.PatternSyntaxException; javni razred RegexDemo {javna statična void main (String [] args) {if (args.length! = 2) {System.err.println ("uporaba: vnos regularnega izraza java RegexDemo"); vrnitev; } // Pretvori zaporedja znakov nove vrstice (\ n) v znake nove vrstice. args [1] = args [1] .replaceAll ("\ n", "\ n"); poskusite {System.out.println ("regex =" + args [0]); System.out.println ("input =" + args [1]); Vzorec p = vzorec.compile (args [0]); Ujemanje m = p.matcher (args [1]); while (m.find ()) System.out.println ("Najdeno [" + m.group () + "], ki se začne pri" + m.start () + "in konča pri" + (m.end () - 1)); } catch (PatternSyntaxException pse) {System.err.println ("Slab regularni izraz:" + pse.getMessage ()); System.err.println ("Opis:" + pse.getDescription ()); System.err.println ("Indeks:" + pse.getIndex ()); System.err.println ("Napačen vzorec:" + pse.getPattern ()); }}}

Prva stvar RegexDemoje glavni () metoda potrjuje svojo ukazno vrstico. Za to sta potrebna dva argumenta: prvi argument je regularni izraz, drugi argument pa je vhodno besedilo, ki se ujema z regularnim izrazom.

Morda boste želeli določiti novo vrstico (\ n) kot del vhodnega besedila. Edini način, da to dosežete, je določiti a \ znak, ki mu sledi znak n znak. glavni () pretvori to zaporedje znakov v vrednost Unicode 10.

Glavnina RegexDemoKoda se nahaja v poskusite-ulov konstruirati. The poskusite blok najprej izpiše določen regularni izraz in vnosno besedilo, nato pa ustvari a Vzorec predmet, ki shranjuje sestavljeni regularni izraz. (Regexes so zbrani za izboljšanje učinkovitosti med ujemanjem vzorcev.) Iz datoteke Vzorec predmet in se uporablja za večkratno iskanje zadetkov, dokler nobeno ne ostane. The ulov blok prikliče različne PatternSyntaxException metode za pridobivanje koristnih informacij o izjemi. Te informacije se nato izpišejo.

V tem trenutku vam ni treba vedeti več o delovanju izvorne kode; postalo bo jasno, ko boste raziskali API v 2. delu, vendar morate sestaviti seznam 1. Zgrabite kodo s seznama 1, nato v ukazno vrstico vnesite naslednje za prevajanje RegexDemo:

javac RegexDemo.java

Vzorec in njegovi konstrukti

Vzorec, prvi od treh razredov, ki vsebujejo API Regex, je sestavljena predstavitev regularnega izraza. VzorecDokumentacija SDK opisuje različne konstrukcije regularnih izrazov, vendar vas bodo deli dokumentacije morda zmedli, če že niste navdušen uporabnik regularnega izraza. Kaj so količniki in v čem je razlika požrešen, nejevoljna, in posesivno količniki? Kaj so razredi znakov, mejne tekme, povratne reference, in izrazi vdelane zastave? Na naslednja vprašanja bom odgovoril v naslednjih poglavjih.

Dobesedni nizi

Najenostavnejši konstrukt regularnega izraza je dobesedni niz. Nekateri deli vhodnega besedila se morajo ujemati z vzorcem tega konstrukta, da se lahko vzorec uspešno ujema. Upoštevajte naslednji primer:

java RegexDemo jabolčni programček

Ta primer poskuša ugotoviti, ali obstaja ujemanje za jabolko vzorec v aplet vnos besedila. Naslednji rezultat razkriva ujemanje:

regex = apple input = aplet Najdeno [apple], ki se začne pri 0 in konča pri 4

Izhod nam pokaže regularni izraz in vnosno besedilo, nato pa označuje uspešno ujemanje jabolko znotraj aplet. Poleg tega predstavlja začetni in končni indeks te tekme: 0 in 4oziroma. Začetni indeks določa prvo mesto besedila, kjer se zgodi ujemanje vzorca; končni indeks določa mesto zadnjega besedila za ujemanje.

Zdaj predpostavimo, da določimo naslednjo ukazno vrstico:

java RegexDemo jabolčni crabapple

Tokrat dobimo naslednjo tekmo z različnimi začetnimi in končnimi indeksi:

regex = jabolko input = crabapple Najdeno [apple], ki se začne pri 4 in konča pri 8

Povratni scenarij, v katerem aplet je regularni izraz in jabolko je vhodno besedilo, ne razkriva ujemanja. Celoten regularni izraz se mora ujemati in v tem primeru vnosno besedilo ne vsebuje a t po jabolko.

Metaznaki

Močnejši konstrukti regularnih izrazov kombinirajo dobesedne znake z metaznaki. Na primer, v a.b, metaznak obdobja (.) predstavlja kateri koli znak, ki se pojavi med a in b. Upoštevajte naslednji primer:

java RegexDemo .ox "Hitra rjava lisica skoči čez lenega vola."

Ta primer določa .ox kot regularni izraz in Hitra rjava lisica preskoči lenobnega vola. kot vhodno besedilo. RegexDemo v besedilu išče zadetke, ki se začnejo s katerim koli znakom in končajo z vol. Ustvari naslednje rezultate:

regex = .ox input = Hitra rjava lisica preskoči lenobnega vola. Najdeno [lisica], ki se začne pri 16 in konča pri 18 Najdeno [vol], ki se začne pri 39 in konča pri 41

Rezultat razkriva dve ujemanji: lisica in vol (z vodilnim presledkom). The . metaznak se ujema z f na prvi tekmi in presledek na drugi tekmi.

Kaj se zgodi, ko zamenjamo .ox z metaznakom obdobja? Kateri izhod je rezultat določitve naslednje ukazne vrstice:

java RegexDemo. "Hitra rjava lisica preskoči lenobnega vola."

Ker se metaznak obdobja ujema s katerim koli znakom, RegexDemo izpiše ujemanje za vsak znak (vključno z znakom končnega obdobja) v vhodnem besedilu:

regularni izraz =. input = Hitra rjava lisica preskoči lenobnega vola. Najdeno [T], ki se začne pri 0 in konča pri 0 Najdeno [h], začenši pri 1 in konča pri 1 Najdeno [e], ki se začne pri 2 in konča pri 2 Najdeno [], ki se začne pri 3 in konča pri 3 Najdeno [q], ki se začne pri 4 in se konča pri 4 Najdeno [u], začenši pri 5 in konča pri 5 Najdeno [i], začenši pri 6 in konča pri 6 Najdeno [c], ki se začne pri 7 in konča pri 7 Najdeno [k], ki se začne pri 8 in konča pri 8 Najdeno [ ], ki se začne pri 9 in konča pri 9 Najdeno [b], ki se začne ob 10 in konča ob 10 Najdeno [r], ki se začne pri 11 in konča ob 11 Najdeno [o], začenši pri 12 in konča ob 12 Najdeno [w], ki se začne pri 13 in konča ob 13 Najdeno [n], ki se začne pri 14 in konča pri 14 Najdeno [], začenši pri 15 in konča ob 15 Najdeno [f], ki se začne pri 16 in konča pri 16 Najdeno [o], začenši pri 17 in konča ob 17 Najdeno [x], začenši ob 18 in konča ob 18 Najdeno [] z začetkom pri 19 in konča ob 19 Najdeno [j] se začne pri 20 in konča ob 20 Najdeno [u] se začne pri 21 in konča ob 21 Najdeno [m] se začne pri 22 in konča ob 22 Najdeno [p] se začne pri 23 in konča pri 23 Najdeno [s] st arting pri 24 in konča pri 24 Najdeno [], ki se začne pri 25 in konča pri 25 Najdeno [o] se začne pri 26 in konča pri 26 Najdeno [v] se začne pri 27 in konča pri 27 Najdeno [e] se začne pri 28 in konča pri 28 Najdeno [r], ki se začne pri 29 in konča pri 29 Najdeno [], ki se začne pri 30 in konča pri 30 Najdeno [t] se začne pri 31 in konča ob 31 Najdeno [h], ki se začne pri 32 in konča pri 32 Najdemo [e], začenši pri 33 in se konča pri 33 Najdeno [], ki se začne pri 34 in konča pri 34 Najdeno [l], začenši pri 35 in konča pri 35 Najdeno [a], ki se začne pri 36 in konča pri 36 Najdeno [z], ki se začne pri 37 in konča pri 37 Najdeno [y ], ki se začne pri 38 in konča pri 38 Najdeno [], ki se začne pri 39 in konča pri 39 Najdeno [o], začenši pri 40 in konča pri 40 Najdeno [x], začenši pri 41 in konča pri 41 Najdeno [.], začenši pri 42 in konča ob 42

Navajanje metaznakov

Če želite določiti . ali kateri koli metaznak kot dobesedni znak v konstruktu regularnih izrazov, citirajte metaznak na enega od naslednjih načinov:

  • Pred metaznakom je znak s poševnico nazaj.
  • Postavite metaznak med \ Q in \ E (npr. \ Q. \ E).

Ne pozabite podvojiti vsakega znaka s poševnico nazaj (kot v \\. ali \ Q. \ E), ki se pojavi v nizovni dobesedni obliki, kot je Redni izraz niza = "\.";. Ne podvojite poševnice nazaj, ko je ta del argumenta ukazne vrstice.

Razredi znakov

Včasih moramo znake, ki bodo povzročili ujemanja, omejiti na določen nabor znakov. Na primer, v besedilu lahko iščemo samoglasnike a, e, jaz, o, in u, kjer vsak pojav samoglasnika kaže na ujemanje. A razred znakov identificira nabor znakov med metaznaki v oglatih oklepajih ([ ]), ki nam pomaga pri izpolnjevanju te naloge. Vzorec podpira enostavne razrede znakov negacije, obsega, združevanja, presečišča in odštevanja. Vse to si bomo ogledali spodaj.

Preprost razred znakov

The preprost razred znakov je sestavljen iz znakov, postavljenih drug ob drugem in se ujema samo s temi znaki. Na primer, [abc] se ujema z znaki a, b, in c.

Upoštevajte naslednji primer:

java RegexDemo [csw] jama

Ta primer se ujema samo c s svojim partnerjem v jama, kot je prikazano v naslednjem izhodu:

regularni izraz = [csw] input = jama Najdeno [c], ki se začne pri 0 in konča pri 0

Razred negativnih znakov

The negacijski razred znakov se začne z ^ metaznak in se ujema samo s tistimi znaki, ki se ne nahajajo v tem razredu. Na primer, [^ abc] se ujema z vsemi znaki, razen a, b, in c.

Razmislite o tem primeru:

java RegexDemo "[^ csw]" jama

Upoštevajte, da so dvojni narekovaji potrebni na moji platformi Windows, katere lupina obravnava ^ kot pobeg.

Ta primer se ujema a, v, in e s svojimi kolegi v jama, kot je prikazano tukaj:

regularni izraz = [^ csw] input = jama Najdeno [a], ki se začne pri 1 in konča pri 1 Najdeno [v], ki se začne pri 2 in konča pri 2 Najdeno [e], ki se začne pri 3 in konča pri 3

Razred znakov obsega

The razred znakov obsega je sestavljen iz dveh znakov, ločenih z vezajem (-). Vsi znaki, ki se začnejo z znakom na levi strani vezaja in končajo z znakom na desni strani vezaja, spadajo v obseg. Na primer, [a-z] se ujema z vsemi malimi črkami. To je enakovredno določanju [abcdefghijklmnopqrstuvwxyz].

Upoštevajte naslednji primer:

java klovn RegexDemo [a-c]

Ta primer se ujema samo c s svojim partnerjem v klovn, kot je prikazano:

regularni izraz = [a-c] input = klovn Najdeno [c], ki se začne pri 0 in konča pri 0

Združevanje več obsegov

Več obsegov lahko združite v isti razred znakov obsega, tako da jih postavite drug ob drugega. Na primer, [a-zA-Z] se ujema z vsemi malimi in velikimi črkami.

Razred znakov unije

The razred znakov zveze je sestavljen iz več vgnezdenih razredov znakov in se ujema z vsemi znaki, ki pripadajo nastali uniji. Na primer, [a-d [m-p]] se ujema z znaki a skozi d in m skozi str.

Upoštevajte naslednji primer:

java RegexDemo [ab [c-e]] abcdef

Ta primer se ujema a, b, c, d, in e s svojimi kolegi v abcdef:

regularni izraz = [ab [ce]] input = abcdef Najdeno [a], ki se začne pri 0 in konča pri 0 Najdeno [b], ki se začne pri 1 in konča pri 1 Najdeno [c], ki se začne pri 2 in konča pri 2 Najdeno [d], začenši pri 3 in konča na 3 Najdeno [e], ki se začne pri 4 in konča pri 4

Razred znakov presečišča

The razred znakov presečišča je sestavljen iz znakov, skupnih vsem ugnezdenim razredom, in se ujema samo s skupnimi znaki. Na primer, [a-z && [d-f]] se ujema z znaki d, e, in f.

Upoštevajte naslednji primer:

java RegexDemo "[aeiouy && [y]]" zabava

Upoštevajte, da so dvojni narekovaji potrebni na moji platformi Windows, katere lupina obravnava & znak kot ločilo ukaza.

Ta primer se ujema samo y s svojim partnerjem v zabava:

regularni izraz = [aeiouy && [y]] input = stranka Najdeno [y], ki se začne pri 4 in konča pri 4
$config[zx-auto] not found$config[zx-overlay] not found