Ricerca…


Idiomi per la corrispondenza di Regex in When Expression

Usando i locali immutabili:

Utilizza meno spazio orizzontale ma più spazio verticale rispetto al modello "anonymous temporaries". Preferibile sul modello "anonymous temporaries" se l'espressione when è in un loop - in questo caso, le definizioni regex devono essere posizionate all'esterno del ciclo.

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 */
}

Usando i temporari anonimi:

Utilizza meno spazio verticale ma più spazio orizzontale rispetto al modello "immutabili locali". Non dovrebbe essere usato se poi when espressione è in un ciclo.

import kotlin.text.regex

var string = /* some string */

when {  
    Regex( /* pattern */ ).matches(string) -> /* do stuff */
    Regex( /* pattern */ ).matches(string) -> /* do stuff */
    /* etc */
}

Utilizzando il modello di visitatore:

Ha il vantaggio di emulare da vicino il "argument-ful" when sintassi. Ciò è utile perché indica più chiaramente l'argomento dell'espressione when , e preclude anche alcuni errori del programmatore che potrebbero derivare dal dover ripetere l'argomento when in ogni whenEntry . O il modello "immutable locals" o "anonymous temporaries" può essere utilizzato con questa implementazione del pattern visitor.

import kotlin.text.regex

var string = /* some string */

when (RegexWhenArgument(string)) {
    Regex( /* pattern */ ) -> /* do stuff */
    Regex( /* pattern */ ) -> /* do stuff */
    /* etc */
}

E la definizione minima della classe wrapper per l'argomento di espressione when :

class RegexWhenArgument (val whenArgument: CharSequence) {
    operator fun equals(whenEntry: Regex) = whenEntry.matches(whenArgument)
    override operator fun equals(whenEntry: Any?) = (whenArgument == whenEntry)
}

Introduzione alle espressioni regolari in Kotlin

Questo post mostra come utilizzare la maggior parte delle funzioni nella classe Regex , lavorare con null in modo sicuro correlato alle funzioni Regex e come le stringhe raw rendano più facile scrivere e leggere i modelli regex.

La classe RegEx

Per lavorare con le espressioni regolari in Kotlin, devi usare la classe Regex(pattern: String) e invocare funzioni come find(..) o replace(..) su quell'oggetto regex.

Un esempio su come utilizzare la classe Regex che restituisce true se la stringa di input contiene c o d:

val regex = Regex(pattern = "c|d")
val matched = regex.containsMatchIn(input = "abc")    // matched: true

La cosa essenziale da capire con tutte le funzioni di Regex è che il risultato è basato sulla corrispondenza tra il pattern regex e la stringa di input . Alcune funzioni richiedono una corrispondenza completa, mentre il resto richiede solo una corrispondenza parziale. La funzione containsMatchIn(..) utilizzata nell'esempio richiede una corrispondenza parziale e viene illustrata più avanti in questo post.

Sicurezza nulla con espressioni regolari

Sia find(..) che matchEntire(..) restituiranno MatchResult? oggetto. Il ? carattere dopo MatchResult è necessario affinchè Kotlin gestisca il null in modo sicuro .

Un esempio che dimostra come Kotlin gestisce nettamente in sicurezza da una funzione Regex , quando la funzione find(..) restituisce null:

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. => ""

Con la funzione orEmpty() , b non può essere nullo e il ? il carattere non è necessario quando si chiamano le funzioni su b .

Se non ti interessa questa gestione sicura dei valori nulli, Kotlin ti permette di lavorare con valori null come in Java con !! personaggi:

a!!.toUpperCase()                      // => KotlinNullPointerException

Stringhe raw nei pattern regex

Kotlin fornisce un miglioramento rispetto a Java con una stringa non elaborata che consente di scrivere schemi regex puri senza doppi backslash, necessari con una stringa Java. Una stringa grezza è rappresentata con una citazione tripla:

"""\d{3}-\d{3}-\d{4}""" // raw Kotlin string
"\\d{3}-\\d{3}-\\d{4}"  // standard Java string

find (input: CharSequence, startIndex: Int): MatchResult?

La stringa di input verrà confrontata con il pattern nell'oggetto Regex . Restituisce un Matchresult? oggetto con il primo testo abbinato dopo startIndex , o null se il modello non corrisponde alla stringa di input . La stringa del risultato viene recuperata da MatchResult? proprietà del value dell'oggetto. Il parametro startIndex è facoltativo con il valore predefinito 0.

Per estrarre il primo numero di telefono valido da una stringa con i dettagli del contatto:

val phoneNumber :String? = Regex(pattern = """\d{3}-\d{3}-\d{4}""")
    .find(input = "phone: 123-456-7890, e..")?.value // phoneNumber: 123-456-7890

Con nessun numero di telefono valido nella stringa di input , la variabile phoneNumber sarà null .

findAll (input: CharSequence, startIndex: Int): Sequence

Restituisce tutte le corrispondenze dalla stringa di input che corrisponde al pattern regex.

Per stampare tutti i numeri separati con lo spazio, da un testo con lettere e cifre:

val matchedResults = Regex(pattern = """\d+""").findAll(input = "ab12cd34ef")
val result = StringBuilder()
for (matchedText in matchedResults) {
    result.append(matchedText.value + " ")
}

println(result) // => 12 34

La variabile matchedResults è una sequenza con oggetti MatchResult . Con una stringa di input senza cifre, la funzione findAll(..) restituirà una sequenza vuota.

matchEntire (input: CharSequence): MatchResult?

Se tutti i caratteri nella stringa di input corrispondono al pattern regex, verrà restituita una stringa uguale input . Altrimenti, verrà restituito null .

Restituisce la stringa di input se l'intera stringa di input è un numero:

val a = Regex("""\d+""").matchEntire("100")?.value             // a: 100
val b = Regex("""\d+""").matchEntire("100 dollars")?.value     // b: null

matches (input: CharSequence): Boolean

Restituisce true se l'intera stringa di input corrisponde al modello regex. Falso altrimenti.

Verifica se due stringhe contengono solo cifre:

val regex = Regex(pattern = """\d+""")
regex.matches(input = "50")             // => true
regex.matches(input = "50 dollars")     // => false

containsMatchIn (input: CharSequence): Boolean

Restituisce true se parte della stringa di input corrisponde al modello regex. Falso altrimenti.

Verifica se due stringhe contengono almeno una cifra:

Regex("""\d+""").containsMatchIn("50 dollars")       // => true
Regex("""\d+""").containsMatchIn("Fifty dollars")    // => false

split (input: CharSequence, limit: Int): List

Restituisce una nuova lista senza tutte le corrispondenze regolari.

Per restituire liste senza cifre:

val a = Regex("""\d+""").split("ab12cd34ef")     // a: [ab, cd, ef]
val b = Regex("""\d+""").split("This is a test") // b: [This is a test]

C'è un elemento nell'elenco per ogni divisione. La prima stringa di input ha tre numeri. Ciò si traduce in una lista con tre elementi.

replace (input: CharSequence, replacement: String): String

Sostituisce tutte le corrispondenze del pattern regex nella stringa di input con la stringa di sostituzione.

Per sostituire tutte le cifre in una stringa con una x:

val result = Regex("""\d+""").replace("ab12cd34ef", "x") // result: abxcdxef


Modified text is an extract of the original Stack Overflow Documentation
Autorizzato sotto CC BY-SA 3.0
Non affiliato con Stack Overflow