yAsH
yAsH

Reputation: 3405

Trimming strings in Scala

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 "hello".

Is there is any built-in method to do this in Scala?

Upvotes: 46

Views: 102531

Answers (6)

user15373586
user15373586

Reputation: 1

Another tailrec function:

def trim(s: String, char: Char): String = {
    if (s.stripSuffix(char.toString).stripPrefix(char.toString) == s)
    {
      s
    } else
    {
      trim(s.stripSuffix(char.toString).stripPrefix(char.toString), char)
    }
  }
scala> trim(",hello",',')
res12: String = hello
scala> trim(",hello,,,,",',')
res13: String = hello

Upvotes: 0

Dirk
Dirk

Reputation: 31053

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"

Upvotes: 103

Pianosaurus
Pianosaurus

Reputation: 5758

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.

Upvotes: 1

chaotic3quilibrium
chaotic3quilibrium

Reputation: 5924

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.

Upvotes: 1

lreeder
lreeder

Reputation: 12206

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.

Upvotes: 12

Jean-Philippe Pellet
Jean-Philippe Pellet

Reputation: 59994

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.

Upvotes: 10

Related Questions