web-dev-qa-db-fra.com

Couper les chaînes en Scala

Comment découper le caractère de début et de fin d'une chaîne dans Scala

Pour des entrées telles que ",hello" ou "hello,", J'ai besoin de la sortie en tant que "hello".

Existe-t-il une méthode intégrée pour le faire dans Scala?

33
yAsH

Essayer

val str = "  foo  "
str.trim

et jetez un oeil à la documentation . Si vous devez vous débarrasser du , caractère, vous pouvez aussi essayer quelque chose comme:

str.stripPrefix(",").stripSuffix(",").trim

Une autre façon de nettoyer le front-end de la chaîne serait

val ignoreable = ", \t\r\n"
str.dropWhile(c => ignorable.indexOf(c) >= 0)

qui prendrait également en charge les chaînes comme ",,, ,,hello"

Et pour faire bonne mesure, voici une toute petite fonction, qui fait tout d'un coup de gauche à droite à travers la chaîne:

def stripAll(s: String, bad: String): String = {

    @scala.annotation.tailrec def start(n: Int): String = 
        if (n == s.length) ""
        else if (bad.indexOf(s.charAt(n)) < 0) end(n, s.length)
        else start(1 + n)

    @scala.annotation.tailrec def end(a: Int, n: Int): String =
        if (n <= a) s.substring(a, n)
        else if (bad.indexOf(s.charAt(n - 1)) < 0) s.substring(a, n)
        else end(a, n - 1)

   start(0)
}

Utilisez comme

stripAll(stringToCleanUp, charactersToRemove)

par exemple.,

stripAll("  , , , hello , ,,,, ", " ,") => "hello"
78
Dirk

Pour couper le caractère de début et de fin dans une chaîne, utilisez un mélange de drop et dropRight:

scala> "bonjour". drop (1) .dropRight (1)

res4: String = bonjour

L'appel de suppression supprime le premier caractère, dropRight supprime le dernier. Notez que ce n'est pas "intelligent" comme l'est la garniture. Si vous n'avez pas de caractère supplémentaire au début de "bonjour", vous le couperez à "Ello". Si vous avez besoin de quelque chose de plus compliqué, le remplacement de regex est probablement la réponse.

11
lreeder

Si vous souhaitez supprimer uniquement des virgules et que vous pouvez en avoir plusieurs à chaque extrémité, vous pouvez procéder comme suit:

str.dropWhile(_ == ',').reverse.dropWhile(_ == ',').reverse

L'utilisation de reverse ici est due au fait qu'il n'y a pas de dropRightWhile.

Si vous regardez une seule virgule possible, stripPrefix et stripSuffix sont le chemin à parcourir, comme indiqué par Dirk.

8

Étant donné que vous souhaitez uniquement supprimer les caractères invalides du préfixe et suffixe d'une chaîne donnée (ne pas parcourir toute la chaîne), voici une minuscule fonction trimPrefixSuffixChars pour effectuer rapidement l'effet souhaité:

def trimPrefixSuffixChars(
    string: String
  , invalidCharsFunction: (Char) => Boolean = (c) => c == ' '
): String =
  if (string.nonEmpty)
    string
      .dropWhile(char => invalidCharsFunction(char))  //trim prefix
      .reverse
      .dropWhile(char => invalidCharsFunction(char)) //trim suffix
      .reverse
  else
    string

Cette fonction fournit une valeur par défaut pour le invalidCharsFunction définissant uniquement le caractère espace ("") comme non valide. Voici à quoi ressemblerait la conversion pour les chaînes d'entrée suivantes:

trimPrefixSuffixChars(" Tx  ")     //returns "Tx"
trimPrefixSuffixChars(" . Tx . ")  //returns ". Tx ."
trimPrefixSuffixChars(" T x  ")    //returns "T x"
trimPrefixSuffixChars(" . T x . ") //returns ". T x ."

Si vous l'avez, vous préférez spécifier votre propre fonction invalidCharsFunction, puis passez-la dans l'appel comme ceci:

trimPrefixSuffixChars(",Tx. ", (c) => !c.isLetterOrDigit)     //returns "Tx"
trimPrefixSuffixChars(" ! Tx # ", (c) => !c.isLetterOrDigit)  //returns "Tx"
trimPrefixSuffixChars(",T x. ", (c) => !c.isLetterOrDigit)    //returns "T x"
trimPrefixSuffixChars(" ! T x # ", (c) => !c.isLetterOrDigit) //returns "T x"

Cela tente de simplifier un certain nombre d'exemples de solutions fournis dans d'autres réponses.

1
chaotic3quilibrium

Quelqu'un a demandé une version regex, qui ressemblerait à ceci:

val trim: Regex = raw"[,\s]*(|.*[^,\s])[,\s]*".r

val result = " , ,, hello, ,," match { case trim(x) => x }

Le résultat est: result: String = hello

L'inconvénient des expressions rationnelles (pas seulement dans ce cas, mais toujours), c'est qu'il est assez difficile à lire pour quelqu'un qui n'est pas déjà intimement familier avec la syntaxe. Le code est agréable et concis, cependant.

0
Pianosaurus