Triedy znakov a najrôznejších reťazcov Java ponúkajú nízkoúrovňovú podporu pre porovnávanie vzorov, ale táto podpora zvyčajne vedie ku komplexnému kódu. Pre jednoduchšie a efektívnejšie kódovanie ponúka Java Regex API. Tento dvojdielny návod vám pomôže začať s regulárnymi výrazmi a rozhraním Regex API. Najskôr rozbalíme tri výkonné triedy sídliace v java.util.regex
balíček, potom preskúmame Vzor
triedy a jej sofistikované konštrukcie zodpovedajúce vzorom.
Čo sú regulárne výrazy?
A regulárny výraz, tiež známy ako a regulárny výraz alebo regexp, je reťazec, ktorého vzor (šablóna) popisuje sadu reťazcov. Vzor určuje, ktoré reťazce patria do množiny. Vzor sa skladá z doslovných znakov a metaznaky, čo sú znaky, ktoré majú namiesto doslovného významu špeciálny význam.
Zhoda vzorov je proces hľadania textu na identifikáciu zápasyalebo reťazce, ktoré zodpovedajú vzoru regulárneho výrazu. Java podporuje porovnávanie vzorov prostredníctvom svojho Regex API. API sa skladá z troch tried -Vzor
, Matcher
a PatternSyntaxException
--všetky umiestnené v java.util.regex
balenie:
Vzor
objekty, známe tiež ako vzory, sú kompilované regulárne výrazy.Matcher
predmety, príp dohadzovači, sú motory, ktoré interpretujú vzory na vyhľadanie zhôd v postupnosť znakov (objekty, ktorých triedy implementujújava.lang.CharSequence
rozhranie a slúžia ako textové zdroje).PatternSyntaxException
objekty popisujú nelegálne vzory regulárneho výrazu.
Java tiež poskytuje podporu pre porovnávanie vzorov rôznymi spôsobmi java.lang.String
trieda. Napríklad, boolovské zhody (reťazec regex)
vracia sa pravda iba ak vyvolávajúci reťazec sa presne zhoduje regulárny výraz
regulárny výraz.
Metódy pohodlia
V zákulisí, zápasy()
a String
Ďalšie pohodlné metódy zamerané na regulárny výraz sú implementované v rámci rozhrania Regex API.
RegexDemo
Vytvoril som RegexDemo
aplikácia na demonštráciu regulárnych výrazov Java a rôznych metód nachádzajúcich sa v Vzor
, Matcher
a PatternSyntaxException
triedy. Tu je zdrojový kód ukážky:
Zoznam 1. Ukážka regexov
import java.util.regex.Matcher; import java.util.regex.Pattern; import java.util.regex.PatternSyntaxException; public class RegexDemo {public static void main (String [] args) {if (args.length! = 2) {System.err.println ("use: java RegexDemo regex input"); návrat; } // Konvertuje sekvencie znakov nového riadku (\ n) na znaky nového riadku. args [1] = args [1] .replaceAll ("\ n", "\ n"); try {System.out.println ("regex =" + args [0]); System.out.println ("input =" + args [1]); Pattern p = Pattern.compile (args [0]); Matcher m = p.matcher (args [1]); while (m.find ()) System.out.println ("Nájdené [" + m.group () + "] začínajúce na„ + m.start () + "a končiace na„ + (m.end () - 1)); } catch (PatternSyntaxException pse) {System.err.println ("Zlý regex:" + pse.getMessage ()); System.err.println ("Popis:" + pse.getDescription ()); System.err.println ("Register:" + pse.getIndex ()); System.err.println ("Nesprávny vzor:" + pse.getPattern ()); }}}
Prvá vec RegexDemo
je hlavný()
metódou je overenie príkazového riadku. To si vyžaduje dva argumenty: prvý argument je regulárny výraz a druhý argument je vstupný text, ktorý sa porovná s regulárnym výrazom.
Možno budete chcieť určiť nový riadok (\ n
) znak ako súčasť vstupného textu. Jediným spôsobom, ako to dosiahnuť, je určiť a \
znak nasledovaný znakom n
znak. hlavný()
prevádza túto postupnosť znakov na hodnotu Unicode 10.
Prevažná časť RegexDemo
Kód sa nachádza v skús
-chytiť
konštrukt. The skús
blok najskôr odošle zadaný regulárny výraz a vstupný text a potom vytvorí a Vzor
objekt, ktorý uchováva skompilovaný regulárny výraz. (Regexy sú kompilované, aby zlepšili výkon pri porovnávaní vzorov.) Z vyhľadávača je extrahovaný porovnávač Vzor
objekt a používa sa na opakované hľadanie zhôd, kým žiadne nezostanú. The chytiť
blok vyvoláva rôzne PatternSyntaxException
metódy na získanie užitočných informácií o výnimke. Tieto informácie sa následne odosielajú.
V tomto okamihu nemusíte vedieť viac o fungovaní zdrojového kódu; to bude jasné, keď preskúmate API v časti 2. Je však potrebné zostaviť zoznam 1. Chyťte kód z výpisu 1 a potom zadajte nasledujúci príkazový riadok, ktorý chcete skompilovať RegexDemo
:
javac RegexDemo.java
Vzor a jeho konštrukty
Vzor
, prvá z troch tried obsahujúcich API Regex, je kompilovaná reprezentácia regulárneho výrazu. Vzor
Dokumentácia SDK popisuje rôzne konštrukcie regexu, ale pokiaľ už nie ste náruživým používateľom regexu, môžu vás niektoré časti dokumentácie zmiasť. Čo sú kvantifikátory a aký je medzi tým rozdiel chamtivý, neochotnýa majetnícky kvantifikátory? Čo sú triedy znakov, hraničné zhody, spätné referenciea vložené príznakové výrazy? Na tieto a ďalšie otázky odpoviem v ďalších častiach.
Doslovné struny
Najjednoduchšou regexovou konštrukciou je doslovný reťazec. Niektorá časť vstupného textu sa musí zhodovať so vzorom tohto konštruktu, aby bola úspešná zhoda so vzorom. Uvažujme o nasledujúcom príklade:
java applet RegexDemo pre jablko
Tento príklad sa pokúša zistiť, či existuje zhoda s parametrom jablko
vzor v applet
vstupný text. Nasledujúci výstup odhalí zhodu:
regex = apple input = applet Nájdené [apple] začínajúce na 0 a končiace 4
Výstup nám ukazuje regulárny výraz a vstupný text, potom označuje úspešnú zhodu s jablko
v rámci applet
. Ďalej predstavuje počiatočný a konečný index príslušnej zhody: 0
a 4
, resp. Počiatočný index identifikuje prvé umiestnenie textu, kde sa vyskytuje zhoda vzoru; koncový index identifikuje posledné umiestnenie textu pre zhodu.
Teraz predpokladajme, že zadáme nasledujúci príkazový riadok:
java RegexDemo jablkový krab
Tentokrát získame nasledujúcu zhodu s rôznymi počiatočnými a koncovými indexmi:
regex = apple input = crabapple Nájdené [apple] začínajúce na 4 a končiace na 8
Opačný scenár, v ktorom applet
je regulárny výraz a jablko
je vstupný text, neodhaľuje žiadnu zhodu. Celý regex sa musí zhodovať a v takom prípade vstupný text neobsahuje a t
po jablko
.
Metaznaky
Výkonnejšie konštrukcie regulárneho výrazu kombinujú doslovné znaky s metaznakmi. Napríklad v a.b
, dobová metaznak (.
) predstavuje akýkoľvek znak, ktorý sa objaví medzi a
a b
. Uvažujme o nasledujúcom príklade:
java RegexDemo .ox "Rýchla hnedá líška skáče cez lenivého vola."
Tento príklad špecifikuje .vôl
ako regex a Rýchla hnedá líška preskočí lenivého vola.
ako vstupný text. RegexDemo
vyhľadáva v texte zhody, ktoré sa začínajú ľubovoľným znakom a končia sa vôl
. Produkuje nasledujúci výstup:
regex = .ox input = Rýchla hnedá líška skáče cez lenivého vola. Nájdené [líška] začínajúca na 16 a končiace na 18 Nájdené [vôl] začínajúce na 39 a končiace o 41
Výstup odhaľuje dve zhody: líška
a vôl
(s vedúcim znakom medzery). The .
metaznak zodpovedá f
v prvom zápase a znak medzery v druhom zápase.
Čo sa stane, keď vymeníme .vôl
s dobovým metaznakom? To znamená, aký výstup vyplynie zo zadania nasledujúceho príkazového riadku:
java RegexDemo. „Rýchla hnedá líška preskočí lenivého vola.“
Pretože metaznak sa zhoduje s akýmkoľvek znakom, RegexDemo
vypíše zhodu pre každý znak (vrátane znaku ukončovacieho obdobia) vo vstupnom texte:
regulárny výraz =. input = Rýchla hnedá líška preskočí lenivého vola. Nájdené [T] začínajúce na 0 a končiace na 0 Nájdené [h] začínajúce na 1 a končiace na 1 Nájdené [e] začínajúce na 2 a končiace na 2 Nájdené [] začínajúce na 3 a končiace o 3 Nájdené [q] začínajúce na 4 a končiace 4 Nájdené [u] začínajúce na 5 a končiace 5 Nájdené [i] začínajúce 6 a končiace 6 Nájdené [c] začínajúce 7 a končiace 7 Nájdené [k] začínajúce 8 a končiace 8 Nájdené [ ] začínajúci na 9 a končiaci na 9 Nájdené [b] začínajúce na 10 a končiace na 10 Nájdené [r] začínajúce na 11 a končiace na 11 Nájdené [o] začínajúce na 12 a končiace o 12 Nájdené [w] začínajúce na 13 a končiace o 13 Nájdené [n] začínajúce na 14 a končiace o 14 Nájdené [] začínajúce na 15 a končiace o 15 Nájdené [f] začínajúce na 16 a končiace o 16 Nájdené [o] začínajúce na 17 a končiace o 17 Nájdené [x] začínajúce v 18 a končí v 18 Nájdené [] začínajúce na 19 a končiace o 19 Nájdené [j] začínajúce na 20 a končiace o 20 Nájdené [u] začínajúce na 21 a končiace o 21 Nájdené [m] začínajúce na 22 a končiace o 22 Nájdené [p] začínajúce na 23 a končiace o 23 Nájdené [s] st arting na 24 a končiace na 24 Nájdené [] začínajúce na 25 a končiace na 25 Nájdené [o] začínajúce na 26 a končiace o 26 Nájdené [v] začínajúce na 27 a končiace o 27 Nájdené [e] začínajúce na 28 a končiace na 28 Nájdené [r] začínajúce na 29 a končiace na 29 Nájdené [] začínajúce na 30 a končiace o 30 Nájdené [t] začínajúce na 31 a končiace o 31 Nájdené [h] začínajúce na 32 a končiace o 32 Nájdené [e] začínajúce na 33 a končiace na 33 Nájdené [] začínajúce na 34 a končiace 34 Nájdené [l] začínajúce na 35 a končiace 35 Nájdené [a] začínajúce na 36 a končiace 36 Nájdené [z] začínajúce na 37 a končiace 37 Nájdené [y ] začínajúci na 38 a končiaci na 38 nájdené [] začínajúce na 39 a končiace na 39 nájdené [o] začínajúce na 40 a končiace na 40 nájdené [x] začínajúce na 41 a končiace 41 nájdené [.] začínajúce na 42 a končiace o 42
Citovanie metaznakov
Špecifikovať .
alebo ľubovoľný metaznak ako doslovný znak v regex konštrukcii, uveďte metaznak jedným z nasledujúcich spôsobov:
- Pred metaznakom použite znak spätnej lomky.
- Vložte metaznak medzi
\ Q
a\ E
(napr.\ Q. \ E
).
Nezabudnite zdvojnásobiť každý znak spätného lomítka (ako v \\.
alebo \ Q. \ E
), ktorý sa nachádza v reťazcovom doslovnom tvare, ako napr Reťazec regex = "\.";
. Nezdvojujte znak spätného lomítka, keď sa zobrazuje ako súčasť argumentu príkazového riadku.
Triedy znakov
Niekedy musíme obmedziť znaky, ktoré budú vytvárať zhody s konkrétnou znakovou sadou. Mohli by sme napríklad vyhľadávať v texte samohlásky a
, e
, i
, o
a u
, kde akýkoľvek výskyt samohlásky naznačuje zhodu. A trieda znakov identifikuje množinu znakov medzi metaznakmi hranatej zátvorky ([ ]
), ktorý nám pomáha splniť túto úlohu. Vzor
podporuje triedy znakov jednoduché, negácia, rozsah, zjednotenie, pretínanie a odčítanie. Na všetky tieto sa pozrieme nižšie.
Jednoduchá trieda znakov
The jednoduchá trieda znakov sa skladá zo znakov umiestnených vedľa seba a zhoduje sa iba s týmito znakmi. Napríklad, [abc]
zodpovedá znakom a
, b
a c
.
Uvažujme o nasledujúcom príklade:
java jaskyňa RegexDemo [csw]
Tento príklad sa iba zhoduje c
so svojim náprotivkom v jaskyňa
, ako je uvedené v nasledujúcom výstupe:
regex = [csw] input = jaskyňa Nájdené [c] začínajúce na 0 a končiace na 0
Trieda negatívnych znakov
The trieda znakov negácie začína na ^
metaznak a zhoduje sa iba s tými znakmi, ktoré sa nenachádzajú v tejto triede. Napríklad, [^ abc]
zodpovedá všetkým znakom okrem a
, b
a c
.
Zvážte tento príklad:
java jaskyňa RegexDemo "[^ csw]"
Upozorňujeme, že úvodzovky sú potrebné na mojej platforme Windows, ktorej shell zaobchádza s ^
postava ako úniková postava.
Tento príklad sa zhoduje a
, v
a e
s ich náprotivkami v jaskyňa
, ako je zobrazené tu:
regex = [^ csw] input = jaskyňa Nájdené [a] začínajúce na 1 a končiace o 1 Nájdené [v] začínajúce na 2 a končiace o 2 Nájdené [e] začínajúce na 3 a končiace o 3
Trieda znakov rozsahu
The trieda znakov rozsahu sa skladá z dvoch znakov oddelených metaznakom spojovníka (-
). Do rozsahu patria všetky znaky začínajúce znakom vľavo od pomlčky a končiace znakom vpravo od pomlčky. Napríklad, [a-z]
sa zhoduje so všetkými malými abecednými znakmi. Je to ekvivalent špecifikácie [abcdefghijklmnopqrstuvwxyz]
.
Uvažujme o nasledujúcom príklade:
java RegexDemo [a-c] klaun
Tento príklad sa iba zhoduje c
so svojim náprotivkom v klaun
, ako je znázornené:
regex = [a-c] vstup = klaun Nájdené [c] začínajúce na 0 a končiace na 0
Zlúčenie viacerých rozsahov
Viaceré rozsahy môžete zlúčiť do jednej triedy znakov rozsahu tak, že ich umiestnite vedľa seba. Napríklad, [a-zA-Z]
zhoduje sa so všetkými malými a veľkými abecednými znakmi.
Trieda znakov Únie
The trieda znakových odborov pozostáva z viacerých vnorených tried znakov a zhoduje sa so všetkými znakmi, ktoré patria do výsledného spojenia. Napríklad, [a-d [m-p]]
zodpovedá znakom a
cez d
a m
cez p
.
Uvažujme o nasledujúcom príklade:
java RegexDemo [ab [c-e]] abcdef
Tento príklad sa zhoduje a
, b
, c
, d
a e
s ich náprotivkami v A b c d e f
:
regex = [ab [ce]] input = abcdef Nájdené [a] začínajúce na 0 a končiace 0 nájdené [b] začínajúce na 1 a končiace 1 nájdené [c] začínajúce na 2 a končiace 2 nájdené [d] začínajúce na 3 a končí sa na 3 Nájdené [e] začínajúce na 4 a končiace na 4
Trieda znakov križovatky
The trieda znakov križovatky sa skladá zo znakov spoločných pre všetky vnorené triedy a zhoduje sa iba so spoločnými znakmi. Napríklad, [a-z && [d-f]]
zodpovedá znakom d
, e
a f
.
Uvažujme o nasledujúcom príklade:
java RegexDemo „[aeiouy && [y]]“ strana
Upozorňujeme, že úvodzovky sú potrebné na mojej platforme Windows, ktorej shell zaobchádza s &
znak ako oddeľovač príkazov.
Tento príklad sa iba zhoduje r
so svojim náprotivkom v večierok
:
regex = [aeiouy && [y]] input = strana Nájdená [y] začínajúca na 4 a končiaca o 4