Trimming strings in Scala

前端 未结 5 1929
无人共我
无人共我 2020-12-25 10:19

How do I trim the starting and ending character of a string in Scala

For inputs such as \",hello\" or \"hello,\", I need the output as

相关标签:
5条回答
  • 2020-12-25 10:58

    To trim the start and ending character in a string, use a mix of drop and dropRight:

    scala> " hello,".drop(1).dropRight(1)

    res4: String = hello

    The drop call removes the first character, dropRight removes the last. Note that this isn't "smart" like trim is. If you don't have any extra character at the start of "hello,", you will trim it to "ello". If you need something more complicated, regex replacement is probably the answer.

    0 讨论(0)
  • 2020-12-25 11:06

    Try

    val str = "  foo  "
    str.trim
    

    and have a look at the documentation. If you need to get rid of the , character, too, you could try something like:

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

    Another way to clean up the front-end of the string would be

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

    which would also take care of strings like ",,, ,,hello"

    And for good measure, here's a tiny function, which does it all in one sweep from left to right through the string:

    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)
    }
    

    Use like

    stripAll(stringToCleanUp, charactersToRemove)
    

    e.g.,

    stripAll("  , , , hello , ,,,, ", " ,") => "hello"
    
    0 讨论(0)
  • 2020-12-25 11:09

    Given you only want to trim off invalid characters from the prefix and the suffix of a given string (not scan through the entire string), here's a tiny trimPrefixSuffixChars function to quickly perform the desired effect:

    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
    

    This function provides a default for the invalidCharsFunction defining only the space (" ") character as invalid. Here's what the conversion would look like for the following input strings:

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

    If you have you would prefer to specify your own invalidCharsFunction function, then pass it in the call like so:

    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"
    

    This attempts to simplify a number of the example solutions provided in other answers.

    0 讨论(0)
  • 2020-12-25 11:11

    Someone requested a regex-version, which would be something like this:

    val result = " , ,, hello, ,,".replaceAll("""[,\s]+(|.*[^,\s])[,\s]+""", "'$1'")
    

    Result is: result: String = hello

    The drawback with regexes (not just in this case, but always), is that it is quite hard to read for someone who is not already intimately familiar with the syntax. The code is nice and concise, though.

    0 讨论(0)
  • 2020-12-25 11:22

    If you want to trim only commas and might have more than one on either end, you could do this:

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

    The use of reverse here is because there is no dropRightWhile.

    If you're looking at a single possible comma, stripPrefix and stripSuffix are the way to go, as indicated by Dirk.

    0 讨论(0)
提交回复
热议问题