3 votes

Kotlin .split() avec plusieurs regex

  Input: """aaaabb\\\\\cc"""
  Pattern: ["""aaa""", """\\""", """\"""]
  Output: [aaa, abb, \\, \\, \, cc]

Comment puis-je diviser Entrée a Sortie l'utilisation de modèles dans Patronage en Kotlin ?

J'ai découvert que Regex("(?<=cha)|(?=cha)") aide les motifs à rester après la division, alors j'ai essayé d'utiliser le bouclage, mais certains des motifs comme '\' et '[' nécessitent une barre oblique inverse d'échappement, alors je ne suis pas en mesure d'utiliser le bouclage pour la division.

EDITAR:

  val temp = mutableListOf<String>()
  for (e in Input.split(Regex("(?<=\\)|(?=\\)"))) temp.add(e)

C'est ce que j'ai fait, mais cela ne fonctionne pas pour les regex multiples, et cela ajoute un "" supplémentaire à la fin de temp si Input se termine par "\".

3voto

Wiktor Stribiżew Points 100073

Vous pouvez utiliser la fonction que j'ai écrite pour une question précédente qui divise par un motif en gardant toutes les sous-chaînes correspondantes et non correspondantes :

private fun splitKeepDelims(s: String, rx: Regex, keep_empty: Boolean = true) : MutableList<String> {
    var res = mutableListOf<String>() // Declare the mutable list var
    var start = 0                     // Define var for substring start pos
    rx.findAll(s).forEach {           // Looking for matches     
        val substr_before = s.substring(start, it.range.first()) // // Substring before match start
        if (substr_before.length > 0 || keep_empty) {
            res.add(substr_before)      // Adding substring before match start
        }
        res.add(it.value)               // Adding match          
        start = it.range.last()+1       // Updating start pos of next substring before match
    }
    if ( start != s.length ) res.add(s.substring(start))  // Adding text after last match if any
    return res
}

Vous avez juste besoin d'un modèle dynamique de votre part. Pattern les éléments de la liste en les joignant avec un | , un opérateur d'alternance en n'oubliant pas d'échapper à tous les objets :

val Pattern = listOf("aaa", """\\""", "\\") // Define the list of literal patterns
val rx = Pattern.map{Regex.escape(it)}.joinToString("|").toRegex() // Build a pattern, \Qaaa\E|\Q\\\E|\Q\\E
val text = """aaaabb\\\\\cc"""
println(splitKeepDelims(text, rx, false))
// => [aaa, abb, \\, \\, \, cc]

Voir le Démonstration Kotlin

Notez qu'entre \Q y \E tous les caractères du motif sont considérés comme des caractères littéraux, et non pas comme des métacaractères spéciaux de la regex.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X