Подтвердить что ты не робот

Строки обрезки в Scala

Как обрезать начальный и конечный символ строки в Scala

Для таких входов, как ",hello" или "hello,", мне нужен выход как "hello".

Есть ли какой-либо встроенный способ сделать это в Scala?

4b9b3361

Ответ 1

Попробуйте

val str = "  foo  "
str.trim

и посмотрите документацию. Если вам нужно избавиться от символа ,, вы также можете попробовать что-то вроде:

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

Другим способом очистки переднего конца строки будет

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

который также позаботится о строках типа ",,, ,,hello"

И для хорошей меры, здесь крошечная функция, которая делает все это одним движением слева направо по строке:

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

Использовать как

stripAll(stringToCleanUp, charactersToRemove)

например.

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

Ответ 2

Чтобы обрезать символ начала и окончания строки, используйте сочетание drop и dropRight:

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

res4: String = hello

Вызов отмены удаляет первый символ, dropRight удаляет последнее. Обратите внимание, что это не "умный", как обрезка. Если у вас нет лишнего персонажа в начале "привет", вы обрезаете его до "ello". Если вам нужно что-то более сложное, замена регулярного выражения, вероятно, является ответом.

Ответ 3

Если вы хотите обрезать только запятые и могут иметь более одного с любого конца, вы можете сделать это:

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

Использование reverse здесь связано с тем, что нет dropRightWhile.

Если вы смотрите на одну возможную запятую, stripPrefix и stripSuffix - это путь, о котором говорит Дирк.

Ответ 4

Если вы хотите только обрезать недопустимые символы из префикса и суффикса данной строки (не сканировать всю строку), здесь крошечный trimPrefixSuffixChars для быстрого выполнения желаемого эффекта:

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

Эта функция предоставляет значение по умолчанию для invalidCharsFunction, определяющего только символ пробела ("") как недействительный. Здесь конверсия будет выглядеть следующим образом:

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

Если вы предпочитаете указывать свою собственную функцию invalidCharsFunction, тогда передайте ее в вызове следующим образом:

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"

Это пытается упростить ряд примеров решений, представленных в других ответах.

Ответ 5

Кто-то запросил regex-версию, которая будет выглядеть примерно так:

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

Результат: result: String = hello

Недостаток регулярных выражений (не только в этом случае, но и всегда) заключается в том, что его довольно трудно читать тем, кто еще не слишком близко знаком с синтаксисом. Код хорош и лаконичен.