Útmutató a karakterek kikerüléséhez a Java RegExps alkalmazásban

1. Áttekintés

A reguláris kifejezések API Java-ban, java.util.regex széles körben használják a minták illesztésére. Ha többet szeretne megtudni, kövesse ezt a cikket.

Ebben a cikkben arra összpontosítunk, hogy megszabaduljunk a karakterektől egy reguláris kifejezéssel, és megmutatjuk, hogyan lehet ezt Java-ban végrehajtani.

2. Speciális RegExp karakterek

A Java reguláris kifejezések API dokumentációja szerint a reguláris kifejezésben vannak speciális karakterek, más néven metakarakterek.

Amikor meg akarjuk engedni a szereplőket a jelenlegi helyzet helyett ahelyett, hogy értelmeznénk őket különleges jelentéseikkel, meg kell menekülnünk tőlük. Ezeknek a karaktereknek a kikerülésével arra kényszerítjük őket, hogy hétköznapi karakterként kezeljék őket, amikor egy karakterláncot illesztenek egy adott reguláris kifejezéshez.

Azok a metakarakterek, amelyek elől általában el kell menekülnünk ilyen módon:

Nézzünk meg egy egyszerű kódpéldát, ahol egy bemenetet egyeztetünk Húr szabályos kifejezésben kifejezett mintával.

Ez a teszt azt mutatja, hogy egy adott bemeneti karakterlánc esetében foof amikor a minta foo. (foo pont karakterrel végződő) illeszkedik, akkor egy értéket ad vissza igaz ami azt jelzi, hogy a mérkőzés sikeres.

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

Elgondolkodhat azon, miért sikeres a meccs, ha a bemenetben nincs pont (.) Karakter Húr?

A válasz egyszerű. A pont (.) Metakarakter - a pont különös jelentősége itt az, hogy a helyén „bármilyen karakter” lehet. Ezért világos, hogy a mérkőzõ hogyan állapította meg a találatot.

Tegyük fel, hogy nem a pont (.) Karaktert akarjuk egyedi jelentéssel kezelni. Ehelyett azt akarjuk, hogy pontjelként értelmezzék. Ez azt jelenti, hogy az előző példában nem akarjuk hagyni a mintát foo. hogy egyezés legyen a bemenetben Húr.

Hogyan kezelnénk egy ilyen helyzetet? A válasz: meg kell kerülnünk a pont (.) karaktert, hogy annak különleges jelentését figyelmen kívül hagyjuk.

A következő szakaszban részletezzük részletesebben.

3. Menekülő karakterek

A reguláris kifejezések Java API dokumentációja szerint kétféleképpen menekülhetünk el a speciális jelentésű karakterektől. Más szóval arra kényszerítve őket, hogy hétköznapi karakterként kezeljék őket.

Lássuk, mik ezek:

  1. Előforduljon metakarakter visszavágással (\)
  2. Mellékeljen egy metakaraktert \ Q és \ E

Ez csak azt jelenti, hogy a korábban látott példában, ha el akarunk menekülni a pont karaktertől, akkor egy visszavágó karaktert kell elhelyeznünk a pont karakter előtt. Alternatív megoldásként a pont karaktert \ Q és \ E közé helyezhetjük.

3.1. Menekülés Backslash használatával

Ez az egyik technika, amelyet használhatunk a metakarakterek elkerüléséhez egy reguláris kifejezésben. Tudjuk azonban, hogy a visszavágó karakter egy menekülési karakter a Java-ban Húr literálok is. Ezért meg kell dupláznunk a visszavágó karaktert, amikor bármilyen karaktert megelőzünk (beleértve magát a \ karaktert is).

Ezért példánkban meg kell változtatnunk a reguláris kifejezést, amint az ebben a tesztben látható:

@Test public void givenRegexWithDotEsc_whenMatchingStr_thenNotMatching () {String strInput = "foof"; Karakterlánc strRegex = "foo \."; assertEquals (hamis, strInput.matches (strRegex)); }

Itt a pont karakter el van kerülve, ezért az egyező egyszerűen pontként kezeli, és megpróbálja megtalálni a ponttal végződő mintát (azaz foo.).

Ebben az esetben visszatér hamis mivel a bemenetben nincs egyezés Húr ahhoz a mintához.

3.2. Menekülés a \ Q & \ E használatával

Alternatív megoldásként használhatjuk \ Q és \ E hogy elkerülje a különleges karaktert. \ Q azt jelzi, hogy az összes karakter legfeljebb \ E meg kell menekülni és \ E azt jelenti, hogy be kell fejeznünk a megkezdett szökést \ Q.

Ez csak azt jelenti, hogy bármi is legyen közöttük \ Q és \ E megmenekülne.

Az itt bemutatott tesztben a hasított() a Húr osztály a neki adott reguláris kifejezés használatával végez egyezést.

Követelményünk, hogy a bemeneti karakterláncot a pipe (|) karakterrel szavakra bontsuk. Ezért erre reguláris kifejezésmintát használunk.

A pipakarakter egy metakarakter, amelyet el kell kerülni a reguláris kifejezésben.

Itt a menekülés úgy történik, hogy a pipakaraktert közé helyezzük \ Q és \ E:

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

4. A Pattern.quote (String S) Módszer

A Pattern.Quote (String S) módszer a java.util.regex.Pattern osztály konvertálja az adott reguláris kifejezés mintázatát Húr szó szerinti mintába Húr. Ez azt jelenti, hogy az összes metakarakter a bemenetben Húr hétköznapi karakterként kezelik.

Ennek a módszernek a használata sokkal kényelmesebb alternatíva lenne \ Q & \ E ahogy beburkolja az adott Húr velük.

Lássuk ezt a módszert működés közben:

@Test public void givenRegexWithPipeEscQuoteMeth_whenSplitStr_thenSplits () sáv

Ebben a gyors tesztben a Pattern.quote () módszert alkalmazzuk az adott regex mintázat elkerülésére és a-vá alakítására Húr szó szerinti. Más szavakkal, elkerüli a számunkra a regex mintában szereplő összes metakaraktert. Hasonló munkát végez, mint \ Q & \ E.

A pipa karakterét elkerüli a Pattern.quote () módszer és a hasított() a-ként értelmezi Húr szó szerint, amellyel osztja a bemenetet.

Mint láthatjuk, ez sokkal tisztább megközelítés, és a fejlesztőknek sem kell emlékezniük az összes menekülési szekvenciára.

Meg kell jegyeznünk Minta.idézet az egész blokkot egyetlen menekülési szekvenciával zárja le. Ha külön-külön szeretnénk elkerülni a karaktereket, akkor egy token-helyettesítő algoritmust kell használnunk.

5. További példák

Nézzük meg, hogyan csereAll () a metódusa java.util.regex.Matcher művek.

Ha le kell cserélnünk egy adott karakter minden előfordulását Húr egy másikkal használhatjuk ezt a módszert úgy, hogy szabályos kifejezést adunk át neki.

Képzelje el, hogy van egy bemenetünk a $ karakter. Az eredmény, amelyet meg akarunk szerezni, ugyanaz a karakterlánc a $ karakter helyébe £.

Ez a teszt bemutatja, hogy a minta hogyan $ megúszása nélkül kerül át:

@Test public void givenRegexWithDollar_whenReplacing_thenNotReplace () {String strInput = "50 dollárt adtam a testvéremnek." + "35 dollárért vett cukorkát. Most 15 dollár van hátra."; Karakterlánc strRegex = "$"; String strReplacement = "£"; String output = "50 fontot adtam a testvéremnek." + "35 fontért vásárolt cukorkát. Most 15 fontja maradt."; P minta = Pattern.compile (strRegex); Matcher m = p.matcher (strInput); assertThat (output, not (equalTo (m.replaceAll (strReplacement)))); }

A teszt ezt állítja $ helytelenül helyettesíti £.

Ha elkerüljük a regex mintát, a helyettesítés helyesen történik, és a teszt sikeresen teljesül, ahogy ez a kódrészletben látható:

@Test public void givenRegexWithDollarEsc_whenReplacing_thenReplace () {String strInput = "50 dollárt adtam a testvéremnek." + "35 dollárért vett cukorkát. Most 15 dollár van hátra."; Karakterlánc strRegex = "\ $"; String strReplacement = "£"; String output = "50 fontot adtam a testvéremnek." + "35 fontért vásárolt cukorkát. Most 15 fontja maradt."; P minta = Pattern.compile (strRegex); Matcher m = p.matcher (strInput); assertEquals (output, m.replaceAll (strReplacement)); }

Vegye figyelembe a \\$ itt, ami megcsinálja a menekülést a $ karakter és sikeresen illeszkedik a mintához.

6. Következtetés

Ebben a cikkben a menekülő karaktereket vizsgáltuk a rendszeres kifejezésekben a Java-ban.

Megbeszéltük, miért kell elkerülni a rendszeres kifejezéseket, és milyen módon lehet elérni.

Mint mindig, a cikkhez kapcsolódó forráskód megtalálható a GitHubon.