Zoeken…
Idioom voor Regex Matching in expressie
Onveranderlijke locals gebruiken:
Gebruikt minder horizontale ruimte, maar meer verticale ruimte dan de sjabloon 'anonieme tijdelijke bestanden'. Voorkeur via "anonymous tijdelijke restauraties" template als de when
expressie in een lus, - dat geval regex definities worden buiten de lus geplaatst.
import kotlin.text.regex
var string = /* some string */
val regex1 = Regex( /* pattern */ )
val regex2 = Regex( /* pattern */ )
/* etc */
when {
regex1.matches(string) -> /* do stuff */
regex2.matches(string) -> /* do stuff */
/* etc */
}
Anonieme tijdelijke functies gebruiken:
Gebruikt minder verticale ruimte maar meer horizontale ruimte dan de sjabloon "onveranderlijke locals". Mag niet worden gebruikt als dan when
expressie in een lus is.
import kotlin.text.regex
var string = /* some string */
when {
Regex( /* pattern */ ).matches(string) -> /* do stuff */
Regex( /* pattern */ ).matches(string) -> /* do stuff */
/* etc */
}
Het bezoekerspatroon gebruiken:
Heeft het voordeel dat de "argument-ful" nauw wordt nagebootst when
syntaxis. Dit is gunstig omdat het duidelijker het argument van de when
expressie aangeeft, en ook bepaalde programmeerfouten uitsluit die kunnen voortvloeien uit het moeten herhalen van het when
argument in elke whenEntry
. Ofwel de "onveranderlijke locals" of de "anonieme tijdelijke" sjabloon kunnen worden gebruikt met deze implementatie van het bezoekerspatroon.
import kotlin.text.regex
var string = /* some string */
when (RegexWhenArgument(string)) {
Regex( /* pattern */ ) -> /* do stuff */
Regex( /* pattern */ ) -> /* do stuff */
/* etc */
}
En de minimale definitie van de wrapper-klasse voor het argument when
expressie:
class RegexWhenArgument (val whenArgument: CharSequence) {
operator fun equals(whenEntry: Regex) = whenEntry.matches(whenArgument)
override operator fun equals(whenEntry: Any?) = (whenArgument == whenEntry)
}
Inleiding tot reguliere expressies in Kotlin
Dit bericht laat zien hoe de meeste functies in de Regex
klasse kunnen worden gebruikt, werken met null dat veilig is gerelateerd aan de Regex
functies, en hoe onbewerkte tekenreeksen het gemakkelijker maken om regex-patronen te schrijven en te lezen.
De RegEx-klasse
Als u met reguliere expressies in Kotlin wilt werken, moet u de klasse Regex(pattern: String)
en functies zoals find(..)
of replace(..)
voor dat regex-object aanroepen.
Een voorbeeld van het gebruik van de Regex
klasse die true retourneert als de input
c of d bevat:
val regex = Regex(pattern = "c|d")
val matched = regex.containsMatchIn(input = "abc") // matched: true
Het essentiële om te begrijpen met alle Regex
functies is dat het resultaat is gebaseerd op het matchen van het regex- pattern
en de input
. Sommige functies vereisen een volledige overeenkomst, terwijl de rest slechts een gedeeltelijke overeenkomst vereist. De functie containsMatchIn(..)
die in het voorbeeld wordt gebruikt, vereist een gedeeltelijke overeenkomst en wordt later in dit bericht uitgelegd.
Nulveiligheid met reguliere expressies
Zowel find(..)
als matchEntire(..)
retourneren een MatchResult?
voorwerp. De ?
karakter na MatchResult
is noodzakelijk voor Kotlin om veilig null te verwerken.
Een voorbeeld dat laat zien hoe Kotlin veilig vanaf een Regex
functie omgaat met null, wanneer de functie find(..)
null retourneert:
val matchResult =
Regex("c|d").find("efg") // matchResult: null
val a = matchResult?.value // a: null
val b = matchResult?.value.orEmpty() // b: ""
a?.toUpperCase() // Still needs question mark. => null
b.toUpperCase() // Accesses the function directly. => ""
Met de functie orEmpty()
kan b
niet null zijn en de ?
teken is overbodig wanneer u functies oproept b
.
Als u niet om deze veilige afhandeling van null-waarden geeft, kunt u met Kotlin met null-waarden werken zoals in Java met de !!
karakters:
a!!.toUpperCase() // => KotlinNullPointerException
Ruwe tekenreeksen in regexpatronen
Kotlin biedt een verbetering ten opzichte van Java met een onbewerkte string die het mogelijk maakt om pure regex-patronen te schrijven zonder dubbele backslashes, die nodig zijn met een Java-string. Een onbewerkte string wordt weergegeven met een drievoudige quote:
"""\d{3}-\d{3}-\d{4}""" // raw Kotlin string
"\\d{3}-\\d{3}-\\d{4}" // standard Java string
find (invoer: CharSequence, startIndex: Int): MatchResult?
De input
wordt vergeleken met het pattern
in het Regex
object. Retourneert het een Matchresult?
object met de eerste overeenkomende tekst na de startIndex
, of null
als het patroon niet overeenkwam met de input
. De resultatiereeks wordt opgehaald uit het MatchResult?
de eigenschap value
object. De parameter startIndex
is optioneel met de standaardwaarde 0.
Om het eerste geldige telefoonnummer te extraheren uit een string met contactgegevens:
val phoneNumber :String? = Regex(pattern = """\d{3}-\d{3}-\d{4}""")
.find(input = "phone: 123-456-7890, e..")?.value // phoneNumber: 123-456-7890
Als er geen geldig telefoonnummer in de input
, is de variabele phoneNumber
null
.
findAll (input: CharSequence, startIndex: Int): Sequence
Retourneert alle overeenkomsten uit de input
die overeenkomen met het regex- pattern
.
Alle getallen gescheiden door een spatie afdrukken, uit een tekst met letters en cijfers:
val matchedResults = Regex(pattern = """\d+""").findAll(input = "ab12cd34ef")
val result = StringBuilder()
for (matchedText in matchedResults) {
result.append(matchedText.value + " ")
}
println(result) // => 12 34
De variabele matchedResults
is een reeks met MatchResult
objecten. Met een input
zonder cijfers findAll(..)
functie findAll(..)
een lege reeks.
matchEntire (input: CharSequence): MatchResult?
Als alle tekens in de input
overeenkomen met het regex- pattern
, wordt een tekenreeks gelijk aan de input
geretourneerd. Anders wordt null
geretourneerd.
Retourneert de invoerreeks als de gehele invoerreeks een getal is:
val a = Regex("""\d+""").matchEntire("100")?.value // a: 100
val b = Regex("""\d+""").matchEntire("100 dollars")?.value // b: null
overeenkomsten (invoer: CharSequence): Boolean
Retourneert true als de hele invoertekenreeks overeenkomt met het regex-patroon. Anders niet.
Test of twee strings alleen cijfers bevatten:
val regex = Regex(pattern = """\d+""")
regex.matches(input = "50") // => true
regex.matches(input = "50 dollars") // => false
bevatMatchIn (invoer: CharSequence): Boolean
Retourneert true als een deel van de invoertekenreeks overeenkomt met het regex-patroon. Anders niet.
Test of twee strings ten minste één cijfer bevatten:
Regex("""\d+""").containsMatchIn("50 dollars") // => true
Regex("""\d+""").containsMatchIn("Fifty dollars") // => false
split (invoer: CharSequence, limit: Int): lijst
Retourneert een nieuwe lijst zonder alle regex-overeenkomsten.
Lijsten zonder cijfers retourneren:
val a = Regex("""\d+""").split("ab12cd34ef") // a: [ab, cd, ef]
val b = Regex("""\d+""").split("This is a test") // b: [This is a test]
Er is één element in de lijst voor elke splitsing. De eerste input
heeft drie cijfers. Dat resulteert in een lijst met drie elementen.
vervangen (invoer: CharSequence, vervanging: String): String
Vervangt alle overeenkomsten van het regex- pattern
in de input
door de vervangende tekenreeks.
Alle cijfers in een string vervangen door een x:
val result = Regex("""\d+""").replace("ab12cd34ef", "x") // result: abxcdxef