Programavimas

Reguliarūs posakiai „Java“, 1 dalis: Rašto derinimas ir „Pattern“ klasė

„Java“ simbolių ir įvairių eilių klasės siūlo žemo lygio palaikymą šablonų derinimui, tačiau ši parama paprastai sukelia sudėtingą kodą. Siekdama paprastesnio ir efektyvesnio kodavimo, „Java“ siūlo „Regex“ API. Ši dviejų dalių mokymo programa padės jums pradėti naudoti įprastus posakius ir „Regex“ API. Pirmiausia išpakuosime tris galingas klases, gyvenančias java.util.regex paketą, tada mes ištirsime Raštas klasė ir jos rafinuoti modelius atitinkantys konstruktai.

atsisiųsti Gauti kodą Atsisiųskite šaltinį, pvz., programas, šioje pamokoje. Sukūrė Jeffas Friesenas, skirtas „JavaWorld“.

Kas yra reguliarūs posakiai?

A Įprasta išraiška, taip pat žinomas kaip a regex arba regexp, yra eilutė, kurios raštas (šablonas) apibūdina eilučių rinkinį. Šablonas nustato, kurios eilutės priklauso rinkiniui. Šabloną sudaro pažodiniai simboliai ir metaženkliai, kurie yra simboliai, turintys ypatingą reikšmę, o ne tiesioginę reikšmę.

Rašto derinimas yra teksto paieškos procesas siekiant nustatyti degtukaiarba eilutės, atitinkančios regex modelį. „Java“ palaiko šablonų derinimą per savo „Regex“ API. API sudaro trys klasės -Raštas, Piršlysir „PatternSyntaxException“--visi įsikūrę java.util.regex paketas:

  • Raštas objektai, dar vadinami modelius, yra sudaryti regexes.
  • Piršlys daiktai, arba rungtynių dalyviai, yra varikliai, kurie interpretuoja modelius, kad surastų atitikmenis simbolių sekas (objektai, kurių klasės įgyvendina java.lang.CharSequence sąsają ir tarnauja kaip teksto šaltiniai).
  • „PatternSyntaxException“ objektai apibūdina neteisėtus regex modelius.

„Java“ taip pat palaiko raštų derinimą įvairiais savo metodais java.lang.Stringas klasė. Pavyzdžiui, loginės rungtynės (eilinis regexas) grįžta tiesa tik jeigu kviečianti eilutė tiksliai sutampa regexregex.

Patogumo metodai

Užkuliusiuose, degtukai() ir StygosKiti regex orientuoti patogumo metodai yra įgyvendinami atsižvelgiant į „Regex“ API.

„RegexDemo“

Aš sukūriau „RegexDemo“ programa, skirta parodyti „Java“ įprastas išraiškas ir įvairius metodus, esančius Raštas, Piršlysir „PatternSyntaxException“ klasės. Štai demo šaltinio kodas:

Išvardinimas 1. Regexes demonstravimas

importuoti java.util.regex.Matcher; importuoti java.util.regex.Pattern; importuoti java.util.regex.PatternSyntaxException; public class RegexDemo {public static void main (String [] args) {if (args.length! = 2) {System.err.println ("naudojimas: java RegexDemo regex įvestis"); grįžti; } // Konvertuoti naujos eilutės (\ n) simbolių sekas į naujos eilutės simbolius. args [1] = args [1] .replaceAll ("\ n", "\ n"); pabandykite {System.out.println ("regex =" + args [0]); System.out.println ("įvestis =" + argumentai [1]); Pattern p = Pattern.compile (argumentai [0]); Atitikmuo m = p.matcheris (argumentai [1]); o (m.find ()) System.out.println ("Rasta [" + m.group () + "] pradedant nuo" + m.start () + "ir baigiantis" + (m.end () - 1)); } gaudyti („PatternSyntaxException pse“) {System.err.println ("Blogas regex:" + pse.getMessage ()); System.err.println ("Aprašas:" + pse.getDescription ()); System.err.println ("Rodyklė:" + pse.getIndex ()); System.err.println ("Neteisingas šablonas:" + pse.getPattern ()); }}}

Pirmas dalykas „RegexDemo“'s pagrindinis () metodas yra patvirtinti savo komandinę eilutę. Tam reikia dviejų argumentų: pirmasis argumentas yra regex, o antrasis argumentas yra įvesties tekstas, kurį reikia suderinti su regex.

Galbūt norėsite nurodyti naują eilutę (\ n) simbolis kaip įvesties teksto dalis. Vienintelis būdas tai pasiekti yra nurodyti a \ simbolis, po kurio seka an n charakteris. pagrindinis () konvertuoja šią simbolių seką į 10 „Unicode“ reikšmę.

Didžioji dalis „RegexDemo“kodas yra bandyti-pagauti sukonstruoti. bandyti blokas pirmiausia išleidžia nurodytą regex ir įvesties tekstą, tada sukuria a Raštas objektas, kuriame saugomas sudarytas regexas. (Regexes sudaromi siekiant pagerinti našumą derinant modelius.) Iš Raštas objektas ir naudojamas pakartotinai ieškoti atitikmenų, kol jų neliks. pagauti blokas kviečia įvairius „PatternSyntaxException“ naudingos informacijos apie išimtį išskyrimo metodai. Ši informacija vėliau pateikiama.

Šiuo metu jums nereikia žinoti daugiau apie šaltinio kodo veikimą; tai paaiškės, kai ištirsite API 2 dalyje. Vis dėlto turite sudaryti 1 sąrašą. Paimkite kodą iš 1 sąrašo, tada į komandinę eilutę įveskite šiuos duomenis „RegexDemo“:

javac RegexDemo.java

Raštas ir jo konstrukcijos

Raštas, pirmoji iš trijų klasių, susidedančių iš „Regex“ API, yra sudarytas taisyklingosios išraiškos atvaizdas. RaštasSDK dokumentuose aprašomi įvairūs regex konstruktai, tačiau, jei dar nesate aistringas regex vartotojas, dokumentai gali jus supainioti. Kas yra kiekybininkai ir koks skirtumas godus, nenoriaiir savininkiškas kiekybininkai? Kas yra veikėjų klasės, ribos atitikmenys, atgalinės nuorodosir įdėtos vėliavos išraiškos? Aš atsakysiu į šiuos ir daugiau klausimų kituose skyriuose.

Pažodinės stygos

Paprasčiausias regexo konstrukcija yra pažodinė eilutė. Tam tikra įvesties teksto dalis turi atitikti šios konstrukcijos modelį, kad modelis atitiktų sėkmingai. Apsvarstykite šį pavyzdį:

java RegexDemo obuolių programėlė

Šiame pavyzdyje bandoma išsiaiškinti, ar yra atitikimas obuolys modelį programėlė įvesties tekstas. Šis rezultatas rodo atitikimą:

regex = obuolio įvestis = programėlė Rasta [obuolys] pradedant nuo 0 ir baigiant 4

Išvestis rodo mums regex ir įvesties tekstą, tada rodo sėkmingą atitikimą obuolys per programėlė. Be to, pateikiami tos rungties pradžios ir pabaigos indeksai: 0 ir 4, atitinkamai. Pradinis indeksas identifikuoja pirmąją teksto vietą, kurioje įvyksta modelio atitiktis; pabaigos indeksas nurodo paskutinę atitikties teksto vietą.

Dabar tarkime, kad nurodome šią komandinę eilutę:

java RegexDemo obuolių krabai

Šį kartą gauname šias rungtynes ​​su skirtingais pradžios ir pabaigos indeksais:

regex = obuolio įvestis = crabapple Rasta [obuolys] pradedant nuo 4 ir baigiant 8

Atvirkštinis scenarijus, kuriame programėlė yra regex ir obuolys yra įvesties tekstas, neatitinka atitikties. Visas regexas turi atitikti, o šiuo atveju įvesties tekste nėra a t po to obuolys.

Metaženkliai

Galingesni regex konstruktai sujungia pažodinius simbolius su metaženkliais. Pavyzdžiui, a.b, laikotarpio metacharakteris (.) reiškia bet kokį simbolį, kuris atsiranda tarp a ir b. Apsvarstykite šį pavyzdį:

java RegexDemo .ox "Greita rudoji lapė šokinėja per tinginį jautį".

Šis pavyzdys nurodo .Jautis kaip regexas ir Greita rudoji lapė šokinėja per tinginį jautį. kaip įvesties tekstą. „RegexDemo“ ieško tekste atitikmenų, kurios prasideda bet kuriuo simboliu ir baigiasi Jautis. Tai sukuria tokią produkciją:

regex = .ox įvestis = Greita rudoji lapė šokinėja per tinginį jautį. Rasta [lapė] prasideda nuo 16 iki baigiasi 18 Rasta [jautė] prasideda nuo 39 iki 41

Rezultatas atskleidžia du atitikmenis: lapė ir Jautis (su pagrindiniu kosmoso personažu). . metacharakteris atitinka f pirmosiose rungtynėse ir kosmoso simbolis antrose rungtynėse.

Kas atsitiks, kai pakeisime .Jautis su laikotarpio metacharakteriu? Tai reiškia, kokia išvestis atsiranda nurodant šią komandinę eilutę:

java RegexDemo. - Greita rudoji lapė šokinėja per tinginį jautį.

Kadangi laikotarpio metachabakteris atitinka bet kurį simbolį, „RegexDemo“ pateikia įvesties tekste kiekvieno simbolio (įskaitant pabaigos taško simbolį) atitiktį:

regex =. įvestis = Greita rudoji lapė šokinėja per tinginį jautį. Rasta [T] pradedant 0 ir baigiant 0 Rasta [h] prasidedant 1 ir baigiant 1 Rasta [e] pradedant 2 ir baigiant 2 Rasta [] pradedant 3 ir baigiant 3 Rasta [q] pradedant 4 ir baigiasi 4 Rasta [u] pradedant 5 ir baigiant 5 Rasta [i] pradedant 6 ir baigiant 6 Rasta [c] pradedant 7 ir baigiant 7 Rasta [k] pradedant 8 ir baigiant 8 Rasta [ ] prasideda 9 ir baigiasi 9 Rasta [b] prasideda 10 ir baigiasi 10 Rasta [r] prasideda 11 ir baigiasi 11 Rasta [o] prasideda 12 ir baigiasi 12 Rasta [w] prasideda 13 ir baigiasi 13 Rasta [n] prasideda 14 ir baigiasi 14 Rasta [] prasideda 15 ir baigiasi 15 Rasta [f] prasideda 16 ir baigiasi 16 Rasta [o] prasideda 17 ir baigiasi 17 Rasta [x] pradedant 18 ir baigiasi 18 Rasta [] prasideda 19 ir baigiasi 19 Rasta [j] prasideda 20 ir baigiasi 20 Rasta [u] prasideda 21 ir baigiasi 21 Rasta [m] prasideda 22 ir baigiasi 22 Rasta [p] prasideda 23 ir baigiasi 23 Rasta [s] st arting 24 ir baigiasi 24 Rasta [] pradedant 25 ir baigiant 25 Rasta [o] pradedant 26 ir baigiant 26 Rasta [v] pradedant 27 ir baigiant 27 Rasta [e] pradedant 28 ir baigiant 28 Rasta [r] pradedant 29 ir baigiant 29 Rasta [] pradedant 30 ir baigiant 30 Rasta [t] pradedant 31 ir baigiant 31 Rasta [h] pradedant 32 ir baigiant 32 Rasta [e] pradedant 33 ir baigiasi 33 Rasta [] pradedant 34 ir baigiant 34 Rasta [l] pradedant 35 ir baigiant 35 Rasta [a] pradedant 36 ir baigiant 36 Rasta [z] pradedant 37 ir baigiant 37 Rasta [y ] pradedant 38 ir baigiant 38 Rasta [] pradedant 39 ir baigiant 39 Rasta [o] pradedant 40 ir baigiant 40 Rasta [x] pradedant 41 ir baigiant 41 Rasta [.] pradedant 42 ir baigiant 42

Cituojame metaženklius

Norėdami nurodyti . ar bet kurį metachabakterį, kaip pažodinį regex konstrukcijos simbolį, cituokite metacharakterį vienu iš šių būdų:

  • Prieš metachakterį pažymėkite atbuline brūkšniu.
  • Įdėkite metacharakterį tarp \ Q ir \ E (pvz., \ Q. \ E).

Nepamirškite padvigubinti kiekvieno atgalinio brūkšnio simbolio (kaip \\. arba Q), kuris pateikiamas eilutės pažodžiui, pvz Eilutės regex = "\.";. Negalima padvigubinti atgalinio brūkšnio simbolio, kai jis rodomas kaip komandinės eilutės argumento dalis.

Simbolių klasės

Kartais turime apriboti simbolius, kurie atitiks konkretų simbolių rinkinį. Pavyzdžiui, galime ieškoti balsių tekste a, e, i, oir u, kai bet koks balsio atsiradimas rodo sutapimą. A veikėjų klasė identifikuoja simbolių rinkinį tarp laužtinių skliaustų metaženklų ([ ]), padedančią mums atlikti šią užduotį. Raštas palaiko paprastąsias, neigimo, diapazono, sąjungos, sankirtos ir atimties simbolių klases. Mes apžvelgsime visus šiuos dalykus žemiau.

Paprasta simbolių klasė

paprasta simbolių klasė susideda iš simbolių, išdėstytų vienas šalia kito, ir atitinka tik tuos simbolius. Pavyzdžiui, [abc] atitinka simbolius a, bir c.

Apsvarstykite šį pavyzdį:

java RegexDemo [csw] urvas

Šis pavyzdys tik atitinka c su savo kolega urvas, kaip parodyta šiame išvestyje:

regex = [csw] input = urvas Rastas [c] pradedant nuo 0 ir baigiantis 0

Neigimo simbolių klasė

neigimo simbolių klasė prasideda ^ metacharakteris ir atitinka tik tuos simbolius, kurie nėra toje klasėje. Pavyzdžiui, [^ abc] atitinka visus simbolius, išskyrus a, bir c.

Apsvarstykite šį pavyzdį:

java RegexDemo "[^ csw]" urvas

Atkreipkite dėmesį, kad dvigubos kabutės yra būtinos mano „Windows“ platformoje, kurios apvalkalas apdoroja ^ personažas kaip pabėgimo personažas.

Šis pavyzdys sutampa a, vir e su savo kolegomis urvas, kaip parodyta čia:

regex = [^ csw] input = urvas Rastas [a] prasidedantis 1 ir baigiantis 1 Rastas [v] pradedant 2 ir baigiant 2 Rastas [e] pradedant 3 ir baigiant 3

Range simbolių klasė

diapazono simbolių klasė susideda iš dviejų simbolių, atskirtų brūkšniu metacharakteriu (-). Visi simboliai, prasidedantys brūkšnio kairėje esančiu simboliu ir baigiantys brūkšnio dešinėje esančiu simboliu, priklauso diapazonui. Pavyzdžiui, [a-z] sutampa su mažosiomis abėcėlės raidėmis. Tai tolygu nurodyti [abcdefghijklmnopqrstuvwxyz].

Apsvarstykite šį pavyzdį:

java RegexDemo [a-c] klounas

Šis pavyzdys tik atitinka c su savo kolega klounas, taip, kaip parodyta:

regex = [a-c] input = klounas Rastas [c] pradedant nuo 0 ir baigiantis 0

Kelių diapazonų sujungimas

Kelis diapazonus galite sujungti į tą pačią diapazono simbolių klasę, pastatydami juos šalia. Pavyzdžiui, [a-zA-Z] sutampa su mažosiomis ir didžiosiomis abėcėlės raidėmis.

Sąjungos simbolių klasė

sąjungos veikėjų klasė susideda iš kelių įdėtų simbolių klasių ir atitinka visus simbolius, priklausančius gautai sąjungai. Pavyzdžiui, [a-d [m-p]] atitinka simbolius a per d ir m per p.

Apsvarstykite šį pavyzdį:

java RegexDemo [ab [c-e]] abcdef

Šis pavyzdys sutampa a, b, c, dir e su savo kolegomis abcdef:

regex = [ab [ce]] input = abcdef Rasta [a] pradedant 0 ir baigiant 0 Rasta [b] pradedant nuo 1 ir baigiant 1 Rasta [c] pradedant 2 ir baigiant 2 Rasta [d] pradedant 3 ir baigiasi 3 Rasta [e] pradedant 4 ir baigiant 4

Sankirtos simbolių klasė

sankirtos simbolių klasė susideda iš simbolių, bendrų visoms įdėtoms klasėms, ir atitinka tik įprastus simbolius. Pavyzdžiui, [a-z && [d-f]] atitinka simbolius d, eir f.

Apsvarstykite šį pavyzdį:

java RegexDemo „[aeiouy && [y]]“ vakarėlis

Atkreipkite dėmesį, kad dvigubos kabutės yra būtinos mano „Windows“ platformoje, kurios apvalkalas apdoroja & simbolis kaip komandų skyriklis.

Šis pavyzdys tik atitinka y su savo kolega vakarėlis:

regex = [aeiouy && [y]] input = party Rasta [y] pradedant nuo 4 ir baigiant 4