Szukaj…


Idiomy dla dopasowania wyrażenia regularnego w wyrażeniu When

Korzystanie z niezmiennych mieszkańców:

Zużywa mniej przestrzeni poziomej, ale więcej przestrzeni pionowej niż szablon „anonimowych tymczasowych”. Preferowana przez „anonimowych tymczasowych” szablon, jeśli when wyrażenie jest w pętli - w tym przypadku, definicje regex powinny być umieszczone na zewnątrz pętli.

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

Korzystanie z anonimowych tymczasowych:

Zużywa mniej przestrzeni pionowej, ale więcej przestrzeni poziomej niż szablon „niezmiennych miejscowych”. Nie powinny być stosowane, jeżeli wtedy when wyrażenie jest w pętli.

import kotlin.text.regex

var string = /* some string */

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

Korzystanie ze wzoru gościa:

Ma tę zaletę, że ściśle naśladuje „pełną argumentację” when składni. Jest to korzystne, ponieważ wyraźniej wskazuje na argument wyrażenia when , a także wyklucza pewne błędy programisty, które mogą wynikać z konieczności powtarzania argumentu when w każdym whenEntry . W tej implementacji można zastosować szablon „niezmiennych miejscowych” lub „anonimowych tymczasowych”.

import kotlin.text.regex

var string = /* some string */

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

I minimalna definicja klasy opakowania dla argumentu when wyrażenie:

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

Wprowadzenie do wyrażeń regularnych w Kotlinie

Ten post pokazuje, jak korzystać z większości funkcji w klasie Regex , pracować z wartością null bezpiecznie związaną z funkcjami Regex , oraz w jaki sposób nieprzetworzone łańcuchy ułatwiają pisanie i odczytywanie wzorców wyrażeń regularnych.

Klasa RegEx

Aby pracować z wyrażeniami regularnymi w Kotlin, musisz użyć klasy Regex(pattern: String) i wywołać funkcje takie jak find(..) lub replace(..) na tym obiekcie wyrażenia regularnego.

Przykład użycia klasy Regex która zwraca true, jeśli ciąg input zawiera c lub d:

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

Zasadniczą rzeczą, którą należy zrozumieć przy wszystkich funkcjach Regex jest to, że wynik opiera się na dopasowaniu pattern wyrażenia regularnego i ciągu input . Niektóre funkcje wymagają pełnego dopasowania, a pozostałe wymagają tylko częściowego dopasowania. Funkcja containsMatchIn(..) zastosowana w tym przykładzie wymaga częściowego dopasowania i jest wyjaśniona w dalszej części tego postu.

Brak bezpieczeństwa dzięki wyrażeniom regularnym

Zarówno find(..) i matchEntire(..) zwrócą MatchResult? obiekt. The ? znak po MatchResult jest konieczny, aby Kotlin mógł bezpiecznie obsługiwać wartość zerową .

Przykład, który pokazuje, jak Kotlin bezpiecznie obsługuje wartość null z funkcji Regex , gdy funkcja find(..) zwraca wartość 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. => ""

Dzięki funkcji orEmpty() b nie może mieć wartości NULL, a znak ? znak nie jest potrzebny, gdy wywołujesz funkcje na b .

Jeśli nie zależy ci na bezpiecznej obsłudze wartości zerowych, Kotlin pozwala na pracę z wartościami zerowymi jak w Javie z !! postacie:

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

Surowe ciągi znaków we wzorach regularnych

Kotlin zapewnia ulepszenie w stosunku do Java z surowym łańcuchem, który umożliwia pisanie czystych wzorców wyrażeń regularnych bez podwójnych odwrotnych ukośników, które są niezbędne w łańcuchu Java. Surowy ciąg jest reprezentowany potrójnym cytatem:

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

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

Łańcuch input zostanie dopasowany do pattern w obiekcie Regex . Zwraca wynik Matchresult? obiekt z pierwszym dopasowanym tekstem po parametrze startIndex lub null jeśli wzorzec nie pasuje do ciągu input . MatchResult? ciąg jest pobierany z MatchResult? właściwość value obiektu. Parametr startIndex jest opcjonalny z wartością domyślną 0.

Aby wyodrębnić pierwszy prawidłowy numer telefonu z ciągu ze szczegółowymi danymi kontaktowymi:

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

Bez poprawnego numeru telefonu w ciągu input zmienna phoneNumber będzie miała null .

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

Zwraca wszystkie dopasowania z ciągu input pasującego do pattern wyrażenia regularnego.

Aby wydrukować wszystkie liczby oddzielone spacją, z tekstu z literami i cyframi:

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

println(result) // => 12 34

Zmienna matchedResults to sekwencja z obiektami MatchResult . W przypadku ciągu input bez cyfr funkcja findAll(..) zwróci pustą sekwencję.

matchEntire (input: CharSequence): MatchResult?

Jeśli wszystkie znaki w ciągu input pasują do pattern wyrażenia regularnego, zwracany jest ciąg równy input . W przeciwnym razie null zostanie zwrócona.

Zwraca ciąg wejściowy, jeśli cały ciąg wejściowy jest liczbą:

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

mecze (input: CharSequence): Boolean

Zwraca true, jeśli cały ciąg wejściowy pasuje do wzorca wyrażenia regularnego. W przeciwnym razie fałszywe.

Sprawdza, czy dwa ciągi zawierają tylko cyfry:

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

zawieraMatchIn (input: CharSequence): Boolean

Zwraca true, jeśli część ciągu wejściowego pasuje do wzorca wyrażenia regularnego. W przeciwnym razie fałszywe.

Sprawdź, czy dwa ciągi zawierają co najmniej jedną cyfrę:

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

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

Zwraca nową listę bez wszystkich dopasowań wyrażeń regularnych.

Aby zwrócić listy bez cyfr:

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

Na liście jest jeden element dla każdego podziału. Pierwszy ciąg input ma trzy liczby. To daje listę z trzema elementami.

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

Zastępuje wszystkie dopasowania pattern wyrażenia regularnego w ciągu input ciągiem zastępującym.

Aby zamienić wszystkie cyfry w ciągu na x:

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


Modified text is an extract of the original Stack Overflow Documentation
Licencjonowany na podstawie CC BY-SA 3.0
Nie związany z Stack Overflow