Buscar..
Modismos para la concordancia de expresiones regulares en cuando la expresión
Usando locales inmutables:
Utiliza menos espacio horizontal pero más espacio vertical que la plantilla de "temporarios anónimos". Es preferible sobre la plantilla de "temporarios anónimos" si la expresión when
está en un bucle; en ese caso, las definiciones de expresiones regulares deben colocarse fuera del bucle.
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 temporarios anónimos:
Utiliza menos espacio vertical pero más espacio horizontal que la plantilla de "locales inmutables". No debe utilizarse si entonces when
expresión está en un bucle.
import kotlin.text.regex
var string = /* some string */
when {
Regex( /* pattern */ ).matches(string) -> /* do stuff */
Regex( /* pattern */ ).matches(string) -> /* do stuff */
/* etc */
}
Usando el patrón de visitante:
Tiene la ventaja de emular estrechamente el "argumento de pleno derecho" when
sintaxis. Esto es beneficioso porque indica más claramente el argumento de la expresión when
, y también evita ciertos errores de programación que podrían surgir al tener que repetir el argumento when
en todos los whenEntry
. Ya sea la plantilla de "locales inmutables" o "temporarios anónimos" se puede usar con esta implementación como patrón de visitante.
import kotlin.text.regex
var string = /* some string */
when (RegexWhenArgument(string)) {
Regex( /* pattern */ ) -> /* do stuff */
Regex( /* pattern */ ) -> /* do stuff */
/* etc */
}
Y la definición mínima de la clase contenedora para el argumento de expresión when
:
class RegexWhenArgument (val whenArgument: CharSequence) {
operator fun equals(whenEntry: Regex) = whenEntry.matches(whenArgument)
override operator fun equals(whenEntry: Any?) = (whenArgument == whenEntry)
}
Introducción a las expresiones regulares en Kotlin.
Esta publicación muestra cómo usar la mayoría de las funciones en la clase Regex
, trabajar con nulos relacionados con las funciones Regex
y cómo las cadenas en bruto facilitan la escritura y lectura de patrones de expresiones regulares.
La clase RegEx
Para trabajar con expresiones regulares en Kotlin, debe usar la Regex(pattern: String)
e invocar funciones como find(..)
o replace(..)
en ese objeto de expresión regular.
Un ejemplo sobre cómo usar la clase Regex
que devuelve verdadero si la cadena de input
contiene c o d:
val regex = Regex(pattern = "c|d")
val matched = regex.containsMatchIn(input = "abc") // matched: true
Lo esencial a entender con todas las funciones Regex
es que el resultado se basa en hacer coincidir el pattern
regex y la cadena de input
. Algunas de las funciones requieren una coincidencia completa, mientras que el resto solo requiere una coincidencia parcial. La función containsMatchIn(..)
utilizada en el ejemplo requiere una coincidencia parcial y se explica más adelante en esta publicación.
Seguridad nula con expresiones regulares.
Tanto find(..)
como matchEntire(..)
devolverán un MatchResult?
objeto. El ?
el carácter después de MatchResult
es necesario para que Kotlin maneje el nulo de forma segura .
Un ejemplo que demuestra cómo Kotlin maneja nulo de forma segura desde una función Regex
, cuando la función find(..)
devuelve 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 función orEmpty()
, b
no puede ser nulo y el ?
el carácter no es necesario cuando llamas funciones en b
.
Si no se preocupan por esta manipulación segura de los valores nulos, Kotlin le permite trabajar con valores nulos como en Java con el !!
caracteres:
a!!.toUpperCase() // => KotlinNullPointerException
Cuerdas crudas en patrones regex
Kotlin proporciona una mejora sobre Java con una cadena sin formato que hace posible escribir patrones de expresiones regulares puras sin doble barra diagonal inversa, que son necesarios con una cadena Java. Una cadena en bruto se representa con una comilla triple:
"""\d{3}-\d{3}-\d{4}""" // raw Kotlin string
"\\d{3}-\\d{3}-\\d{4}" // standard Java string
find (entrada: CharSequence, startIndex: Int): MatchResult?
La cadena de input
se comparará con el pattern
en el objeto Regex
. ¿Devuelve un Matchresult?
objeto con el primer texto coincidente después del startIndex
, o null
si el patrón no coincide con la cadena de input
. La cadena de resultados se recupera de MatchResult?
propiedad del value
del objeto. El parámetro startIndex
es opcional con el valor predeterminado 0.
Para extraer el primer número de teléfono válido de una cadena con detalles de contacto:
val phoneNumber :String? = Regex(pattern = """\d{3}-\d{3}-\d{4}""")
.find(input = "phone: 123-456-7890, e..")?.value // phoneNumber: 123-456-7890
Sin un número de teléfono válido en la cadena de input
, la variable phoneNumber
será null
.
findAll (input: CharSequence, startIndex: Int): secuencia
Devuelve todas las coincidencias de la cadena de input
que coincide con el pattern
expresiones regulares.
Para imprimir todos los números separados por espacios, desde un texto con letras y dígitos:
val matchedResults = Regex(pattern = """\d+""").findAll(input = "ab12cd34ef")
val result = StringBuilder()
for (matchedText in matchedResults) {
result.append(matchedText.value + " ")
}
println(result) // => 12 34
La variable matchedResults
es una secuencia con objetos MatchResult
. Con una cadena de input
sin dígitos, la función findAll(..)
devolverá una secuencia vacía.
matchEntire (input: CharSequence): MatchResult?
Si todos los caracteres en la cadena de input
coinciden con el pattern
expresiones regulares, se devolverá una cadena igual a la input
. De lo contrario, se devolverá null
.
Devuelve la cadena de entrada si toda la cadena de entrada es un número:
val a = Regex("""\d+""").matchEntire("100")?.value // a: 100
val b = Regex("""\d+""").matchEntire("100 dollars")?.value // b: null
partidos (entrada: CharSequence): booleano
Devuelve verdadero si toda la cadena de entrada coincide con el patrón de expresiones regulares. Falso de lo contrario.
Comprueba si dos cadenas contienen solo dígitos:
val regex = Regex(pattern = """\d+""")
regex.matches(input = "50") // => true
regex.matches(input = "50 dollars") // => false
contieneMatchIn (entrada: CharSequence): Boolean
Devuelve verdadero si parte de la cadena de entrada coincide con el patrón de expresiones regulares. Falso de lo contrario.
Probar si dos cadenas contienen al menos un dígito:
Regex("""\d+""").containsMatchIn("50 dollars") // => true
Regex("""\d+""").containsMatchIn("Fifty dollars") // => false
split (entrada: CharSequence, limit: Int): Lista
Devuelve una nueva lista sin todas las coincidencias de expresiones regulares.
Para devolver listas sin dígitos:
val a = Regex("""\d+""").split("ab12cd34ef") // a: [ab, cd, ef]
val b = Regex("""\d+""").split("This is a test") // b: [This is a test]
Hay un elemento en la lista para cada división. La primera cadena de input
tiene tres números. Eso resulta en una lista con tres elementos.
reemplazar (entrada: CharSequence, reemplazo: cadena): cadena
Reemplaza todas las coincidencias del pattern
expresiones regulares en la cadena de input
con la cadena de reemplazo.
Para reemplazar todos los dígitos en una cadena con una x:
val result = Regex("""\d+""").replace("ab12cd34ef", "x") // result: abxcdxef