Rendszeres kifejezések Kotlinban
1. Bemutatkozás
Megtalálhatjuk a rendszeres kifejezések használatát (vagy visszaélését) nagyjából mindenféle szoftverben, a gyors szkriptektől a hihetetlenül összetett alkalmazásokig.
Ebben a cikkben megtudjuk, hogyan használjuk a reguláris kifejezéseket Kotlinban.
Nem fogunk tárgyalni a reguláris kifejezés szintaxisáról; a cikk megfelelő követéséhez általában ismerni kell a szabályos kifejezéseket, és kifejezetten ajánlott a Java Pattern szintaxisának ismerete.
2. Beállítás
Bár a reguláris kifejezések nem részei a Kotlin nyelvének, a standard könyvtárral együtt érkeznek.
Valószínűleg már a projektünk függősége is:
org.jetbrains.kotlin kotlin-stdlib 1.2.21
A kotlin-stdlib legújabb verzióját megtalálhatjuk a Maven Central-on.
3. Reguláris kifejezés objektum létrehozása
A reguláris kifejezések a kotlin.text.Regex osztály. Többféleképpen is létrehozhatunk egyet.
Lehetőség van a Regex konstruktőr:
Regex ("a [bc] + d?")
vagy hívhatjuk a toRegex módszer a Húr:
"a [bc] + d?". toRegex ()
Végül használhatunk statikus gyári módszert:
Regex.fromLiteral ("a [bc] + d?")
Mentsen el a következő szakaszban ismertetett különbségektől, ezek az opciók egyenértékűek és megfelelnek a személyes preferenciáknak. Csak ne feledje, hogy következetes legyen!
Tipp: A reguláris kifejezések gyakran tartalmaznak olyan karaktereket, amelyeket a menekülési szekvenciaként értelmeznének Húr literálok. Így nyersen is felhasználhatjuk Húrok elfelejteni a menekülés több szintjét:
"" "a [bc] + d? \ W" "". toRegex ()
3.1. Illesztési opciók
Mind a Regex kivitelező és a toRegex módszer lehetővé teszi számunkra, hogy egyetlen további opciót vagy halmazt adjunk meg:
Regex ("a (b | c) + d?", CANON_EQ) Regex ("a (b | c) + d?", SetOf (DOT_MATCHES_ALL, MEGJEGYZÉSEK)) "a (b | c) + d?". ToRegex (MULTILINE) "a (b | c) + d?". ToRegex (setOf (IGNORE_CASE, MEGJEGYZÉSEK, UNIX_LINES))
Az opciókat a RegexOption osztály, amelyet kényelmesen statikusan importáltunk a fenti példában:
- IGNORE_CASE - lehetővé teszi a kis- és nagybetűk közötti egyezést
- MULTILINE - megváltoztatja a jelentését ^ és $ (lát Minta)
- SZÓ SZERINTI - a metakaraktereknek vagy a menekülési szekvenciáknak nincs különösebb értelme
- UNIX_LINES - ebben a módban csak a \ n vonalterminálóként ismerik el
- HOZZÁSZÓLÁSOK - engedélyezi a szóközöket és a mintához fűzött megjegyzéseket
- DOT_MATCHES_ALL - azt eredményezi, hogy a pont bármilyen karakterrel megegyezzen, beleértve a sorvégződést is
- CANON_EQ - lehetővé teszi az egyenértékűséget kanonikus bontással (lásd a mintát)
4. Párosítás
A reguláris kifejezéseket elsősorban a bemenet megfeleltetésére használjuk Húrok, és néha kivonni vagy kicserélni részeiket.
Most részletesen megvizsgáljuk a Kotlin által kínált módszereket Regex osztály az egyezéshez Húrok.
4.1. Részleges vagy teljes mérkőzések ellenőrzése
Ezekben a felhasználási esetekben érdekel minket tudva, hogy a Húr vagy az a része Húr kielégíti a reguláris kifejezésünket.
Ha csak részleges meccsre van szükségünk, használhatjuk tartalmazzaMatchIn:
val regex = "" "a ([bc] +) d?" "". toRegex () assertTrue (regex.containsMatchIn ("xabcdy"))
Ha az egészet akarjuk Húr hogy helyette illeszkedjünk, használjuk mérkőzések:
assertTrue (regex.matches ("abcd"))
Vegye figyelembe, hogy használhatjuk mérkőzések infix operátorként is:
assertFalse (a regex megfelel az "xabcdy" kifejezésnek)
4.2. Megfelelő komponensek kinyerése
Ezekben a felhasználási esetekben szeretnénk hogy megfeleljen a Húr szabályos kifejezéssel szemben, és vonja ki a Húr.
Esetleg az egészet szeretnénk egyeztetni Húr:
val matchResult = regex.matchEntire ("abbccbbd")
Vagy érdemes megkeresni az első alszöveget, amely megfelel:
val matchResult = regex.find ("abcbabbd")
Vagy talán megtalálja az összes megfelelő alsztringet egyszerre, mint a Készlet:
val matchResults = regex.findAll ("abcb abbd")
Mindkét esetben, ha a meccs sikeres, az eredmény a játék egy vagy több példánya lesz MatchResult osztály. A következő szakaszban megtudjuk, hogyan kell használni.
Ha a mérkőzés nem sikeres, akkor ezek a módszerek visszatérnek nulla vagy az üres Készlet esetében Találd meg mindet.
4.3. A MatchResult Osztály
A MatchResult osztály néhány bemeneti karakterlánc sikeres illesztését jelenti egy reguláris kifejezéssel szemben; akár teljes, akár részleges egyezéseket (lásd az előző részt).
Mint ilyen, van egy érték, ami az egyeztetett Húr vagy alszöveg:
val regex = "" "a ([bc] +) d?" "". toRegex () val matchResult = regex.find ("abcb abbd") assertEquals ("abcb", matchResult.value)
És van egy hatótávolság indexek, amelyek jelzik, hogy a bemenet mely része egyezik:
assertEquals (IntRange (0, 3), matchResult.range)
4.4. Csoportok és szerkezetátalakítás
Csoportokat (egyeztetett részstruktúrákat) is kivonhatunk ezekből MatchResult példányok.
Megszerezhetjük őket Húrok:
assertEquals (listOf ("abcb", "bcb"), matchResult.groupValues)
Vagy úgy is tekinthetjük őket MatchGroup tárgyak, amelyek a érték és a hatótávolság:
assertEquals (IntRange (1, 3), matchResult.groups [1] .range)
A 0 indexű csoport mindig az egész egyeztetett Húr. A 0-nál nagyobb indexek ehelyett a reguláris kifejezés csoportjait jelölik, zárójelekkel határolva, mint pl ([bc] +) példánkban.
Mi is roncsolhatunk MatchResult példányok egy hozzárendelési utasításban:
val regex = "" "[[\ w \ s] +) (\ d +) éves" "". toRegex () val matchResult = regex.find ("Mickey Mouse 95 éves") val (név, életkor ) = matchResult !!. destructured assertEquals ("Miki egér", név) assertEquals ("95", életkor)
4.5. Több mérkőzés
MatchResult is van egy következő módszer, amelyet használhatunk hogy megszerezzük a bemenet következő egyezését Húr a reguláris kifejezéssel szemben, ha van ilyen:
val regex = "" "a ([bc] +) d?" "". toRegex () var matchResult = regex.find ("abcb abbd") assertEquals ("abcb", matchResult !!. value) matchResult = matchResult. next () assertEquals ("abbd", matchResult !!. value) matchResult = matchResult.next () assertNull (matchResult)
Ahogy látjuk, következő null értéket ad vissza, ha nincs több találat.
5. Csere
A reguláris kifejezések másik gyakori használata a megfelelő alszekciók cseréje másikkal Húrok.
Erre a célra két módszer áll rendelkezésre, amelyek a standard könyvtárban könnyen elérhetők.
Egy, cserélje ki, az illesztés minden előfordulásának helyettesítésére szolgál Húr:
val regex = "" "(piros | zöld | kék)" "". toRegex () val beautiful = "A rózsák pirosak, az ibolyák kékek" val komor = regex.csere (gyönyörű, "sötét") állít sötét, az ibolya sötét ", komor)
A másik, firstFirst, csak az első előfordulás helyettesítésére szolgál:
val shiny = regex.replaceFirst (gyönyörű, "szivárvány") assertEquals ("A rózsák szivárványosak, az ibolyák kékek", fényesek)
5.1. Összetett cserék
Mert fejlettebb forgatókönyvek, amikor nem akarjuk a meccseket állandóval helyettesíteni Húrok, de szeretnénk transzformáció alkalmazására helyette, Regex még mindig megadja nekünk, amire szükségünk van.
Írd be a cserélje ki túlterhelés bezárással:
val reallyBeautiful = regex.pótolja (gyönyörű) {m -> m.value.toUpperCase () + "!" } assertEquals ("A rózsák RED !, az Ibolya KÉK!", igazánGyönyörű)
Mint láthatjuk, minden mérkőzéshez kiszámíthatjuk a helyettesítést Húr felhasználva azt a mérkőzést.
6. Hasadás
Végül szeretnénk megosztani a Húr egy reguláris kifejezés szerinti részstruktúrák listájába. Ismét Kotliné Regex fedett minket:
val regex = "" "\ W +" "". toRegex () val beautiful = "A rózsák pirosak, az ibolyák kékek" assertEquals (listOf ("Rózsa", "vannak", "piros", "Ibolya", "vannak") , "kék"), regex.split (gyönyörű))
Itt a reguláris kifejezés egy vagy több nem szóból álló karakterrel egyezik, így a felosztási művelet eredménye a szavak listája.
Korlátozhatunk az eredményül kapott lista hosszát is:
assertEquals (listOf ("Rózsa", "vannak", "piros", "Ibolya kék"), regex.split (gyönyörű, 4))
7. Java interoperabilitás
Ha át kell adnunk a reguláris kifejezésünket Java kódnak, vagy valamilyen más JVM nyelvi API-nak, amely egy példányra számít java.util.regex.Pattern, egyszerűen konvertálhatjuk a Regex:
regex.toPattern ()
8. Következtetések
Ebben a cikkben megvizsgáltuk a rendszeres kifejezés támogatását a Kotlin standard könyvtárban.
További információkért lásd a Kotlin-referenciát.
Ezeknek a példáknak és kódrészleteknek a megvalósítása megtalálható a GitHub projektben - ez egy Maven projekt, ezért könnyen importálhatónak és futtathatónak kell lennie.