Regulárne výrazy v Kotline

1. Úvod

Používanie (alebo zneužívanie) regulárnych výrazov môžeme nájsť v takmer každom druhu softvéru, od rýchlych skriptov až po neuveriteľne zložité aplikácie.

V tomto článku uvidíme, ako používať regulárne výrazy v Kotline.

Nebudeme diskutovať o syntaxi regulárneho výrazu; na adekvátne sledovanie článku je všeobecne nevyhnutná znalosť regulárnych výrazov a osobitne sa odporúča znalosť syntaxe Java Pattern.

2. Inštalácia

Aj keď regulárne výrazy nie sú súčasťou jazyka Kotlin, majú štandardnú knižnicu.

Pravdepodobne to už máme ako závislosť nášho projektu:

 org.jetbrains.kotlin kotlin-stdlib 1.2.21 

Najnovšiu verziu kotlin-stdlib nájdeme na serveri Maven Central.

3. Vytvorenie objektu regulárneho výrazu

Regulárne výrazy sú inštanciami kotlin.text.Regex trieda. Jeden môžeme vytvoriť niekoľkými spôsobmi.

Možnosťou je zavolať na Regulárny výraz konštruktér:

Regex ("a [bc] + d?")

alebo môžeme zavolať toRegex metóda na a Reťazec:

„a [bc] + d?". toRegex ()

Nakoniec môžeme použiť statickú továrenskú metódu:

Regex.fromLiteral ("a [bc] + d?")

Okrem rozdielu vysvetleného v nasledujúcej časti sú tieto možnosti ekvivalentné a zodpovedajú osobným preferenciám. Len nezabudnite na dôslednosť!

Tip: Regulárne výrazy často obsahujú znaky, ktoré by sa v nich interpretovali ako únikové sekvencie String literály. Môžeme tak použiť surové Struny zabudnúť na niekoľko úrovní úniku:

"" "a [bc] + d? \ W" "". toRegex ()

3.1. Možnosti zhody

Obaja Regulárny výraz konštruktér a toRegex metóda nám umožňuje určiť jednu ďalšiu možnosť alebo množinu:

Regex ("a (b | c) + d?", CANON_EQ) Regex ("a (b | c) + d?", SetOf (DOT_MATCHES_ALL, KOMENTÁRE)) "a (b | c) + d?". ToRegex (MULTILINE) "a (b | c) + d?". ToRegex (setOf (IGNORE_CASE, COMMENTS, UNIX_LINES))

Možnosti sú vymenované v RegexOption triedy, ktoré sme pohodlne staticky importovali v príklade vyššie:

  • IGNORE_CASE - umožňuje rozlišovanie malých a veľkých písmen
  • MULTILINE - mení význam ^ a $ (viď Vzor)
  • LITERÁLNE - spôsobí, že metaznakom alebo únikovým sekvenciám vo vzore nebude mať žiadny zvláštny význam
  • UNIX_LINES - v tomto režime iba \ n je rozpoznaný ako terminátor linky
  • KOMENTÁRE Zatiaľ žiadne informácie - umožňuje medzery a komentáre vo vzore
  • DOT_MATCHES_ALL - spôsobí, že sa bodka zhoduje s akýmkoľvek znakom vrátane zakončenia riadku
  • CANON_EQ - umožňuje ekvivalenciu pomocou kanonického rozkladu (pozri vzor)

4. Zhoda

Regulárne výrazy používame primárne na zosúladenie vstupu Struny, a niekedy extrahovať alebo vymeniť ich časti.

Teraz sa pozrieme podrobne na metódy, ktoré ponúka Kotlin Regulárny výraz trieda na párovanie Struny.

4.1. Kontrola čiastkových alebo celkových zápasov

V týchto prípadoch použitia nás zaujíma vedieť, či a String alebo časť a String uspokojuje náš regulárny výraz.

Ak potrebujeme iba čiastočnú zhodu, môžeme použiť containsMatchIn:

val regex = "" "a ([bc] +) d?" "". toRegex () assertTrue (regex.containsMatchIn ("xabcdy"))

Ak chceme celok String namiesto toho použijeme zápasy:

assertTrue (regex.matches ("abcd"))

Všimnite si, že môžeme použiť zápasy aj ako operátor infix:

assertFalse (regulárny výraz zodpovedá výrazu „xabcdy“)

4.2. Extrahovanie zodpovedajúcich komponentov

V týchto prípadoch použitia chceme zodpovedať a String proti regulárnemu výrazu a extrahovať časti String.

Možno by sme chceli zosúladiť celý Reťazec:

val matchResult = regex.matchEntire ("abbccbbd")

Alebo možno budeme chcieť nájsť prvý podreťazec, ktorý zodpovedá:

val matchResult = regex.find ("abcbabbd")

Alebo možno nájdite všetky zodpovedajúce podreťazce naraz, ako a Nastaviť:

val matchResults = regex.findAll ("abcb abbd")

V obidvoch prípadoch, ak je zápas úspešný, výsledkom bude jeden alebo viac prípadov MatchResult trieda. V nasledujúcej časti uvidíme, ako sa to bude používať.

Ak zápas nie je úspešný, tieto metódy sa vrátia nulový alebo prázdny Nastaviť v prípade findAll.

4.3. The MatchResult Trieda

Prípady MatchResult trieda predstavuje úspešné zhody nejakého vstupného reťazca s regulárnym výrazom; buď úplné alebo čiastočné zhody (pozri predchádzajúcu časť).

Ako také majú hodnotu, ktorá je zhodná String alebo podreťazec:

val regex = "" "a ([bc] +) d?" "". toRegex () val matchResult = regex.find ("abcb abbd") assertEquals ("abcb", matchResult.value)

A majú rozsah indexov označujúcich, ktorá časť vstupu sa zhodovala:

assertEquals (IntRange (0, 3), matchResult.range)

4.4. Skupiny a deštrukturalizácia

Môžeme tiež extrahovať skupiny (párované podreťazce) z MatchResult inštancie.

Môžeme ich získať ako Struny:

assertEquals (listOf ("abcb", "bcb"), matchResult.groupValues)

Alebo ich tiež môžeme zobraziť ako MatchGroup predmety pozostávajúce z a hodnotu a a rozsah:

assertEquals (IntRange (1, 3), matchResult.groups [1]. rozsah)

Skupina s indexom 0 je vždy celá zhodná String. Indexy väčšie ako 0 namiesto toho predstavujú skupiny v regulárnom výraze ohraničené zátvorkami, ako napr ([bc] +) v našom príklade.

Môžeme tiež zničiť MatchResult inštancie vo vyhlásení o priradení:

val regex = "" "([\ w \ s] +) je (\ d +) rokov" "". toRegex () val matchResult = regex.find ("Mickey Mouse má 95 rokov") val (meno, vek) ) = matchResult !!. zničená assertEquals ("Mickey Mouse", meno) assertEquals ("95", vek)

4.5. Viac zápasov

MatchResult má tiež a Ďalšie metódu, ktorú môžeme použiť na získanie ďalšej zhody vstupu String proti regulárnemu výrazu, ak existuje:

val regex = "" "a ([bc] +) d?" "". toRegex () var matchResult = regex.find ("abcb abbd") assertEquals ("abcb", matchResult !!. hodnota) matchResult = matchResult. next () assertEquals ("abbd", matchResult !!. value) matchResult = matchResult.next () assertNull (matchResult)

Ako vidíme, Ďalšie vráti null, keď už nie sú k dispozícii žiadne zhody.

5. Výmena

Ďalším bežným používaním regulárnych výrazov je nahradenie zodpovedajúcich podreťazcov inými Struny.

Na tento účel máme v štandardnej knižnici ľahko dostupné dve metódy.

Jeden, vymeniť, slúži na nahradenie všetkých výskytov zhody Reťazec:

val regex = "" (červená | zelená | modrá) "" ". toRegex () val beautiful =" Ruže sú červené, fialové modré "val grim = regex.replace (krásne," tmavé ") assertEquals (" Ruže sú tmavá, fialové sú tmavé ", pochmúrna)

Ostatný, nahradiťPrvý, slúži na nahradenie iba prvého výskytu:

val shiny = regex.replaceFirst (krásny, „dúhový“) assertEquals („Ruže sú dúhové, fialové sú modré“, lesklé)

5.1. Komplexné náhrady

Pre pokročilejšie scenáre, keď nechceme nahradiť zápasy konštantou Struny, ale chceme použiť transformáciu namiesto toho Regulárny výraz stále nám dáva to, čo potrebujeme.

Zadajte znak vymeniť preťaženie pri uzavretí:

val reallyBeautiful = regex.replace (beautiful) {m -> m.value.toUpperCase () + "!" } assertEquals („Ruže sú ČERVENÉ !, Fialové sú MODRÉ!“, naozajBeautiful)

Ako vidíme, pre každý zápas môžeme vypočítať náhradu String pomocou tohto zápasu.

6. Štiepanie

Nakoniec by sme možno chceli rozdeliť a String do zoznamu podreťazcov podľa regulárneho výrazu. Opäť Kotlinova Regulárny výraz má nás kryté:

val regex = "" "\ W +" "" toRegex () val beautiful = "Ruže sú červené, fialové sú modré" assertEquals (listOf ("Roses", "sú", "červené", "fialové", "sú" , „modrá“), regex.split (krásna))

Tu sa regulárny výraz zhoduje s jedným alebo viacerými neslovnými znakmi, takže výsledkom operácie rozdelenia je zoznam slov.

Môžeme tiež obmedziť dĺžku výsledného zoznamu:

assertEquals (listOf ("Ruže", "sú", "červené", "Fialové sú modré"), regex.split (krásne, 4))

7. Interoperabilita Java

Ak potrebujeme odovzdať náš regulárny výraz do kódu Java alebo do iného API jazyka JVM, ktoré očakáva inštanciu java.util.regex.Vzor, môžeme jednoducho previesť naše Regulárny výraz:

regex.toPattern ()

8. Závery

V tomto článku sme preskúmali podporu regulárnych výrazov v štandardnej knižnici Kotlin.

Ďalšie informácie nájdete v dokumentácii Kotlin.

Implementáciu všetkých týchto príkladov a útržkov kódu nájdete v projekte GitHub - toto je projekt Maven, takže by malo byť ľahké ho importovať a spustiť tak, ako je.


$config[zx-auto] not found$config[zx-overlay] not found