Как сопоставить строку по префиксу и получить остальные?

Я могу написать такой код:

str match {
    case s if s.startsWith("!!!") => s.stripPrefix("!!!")
    case _ =>
}

Но я хочу знать, есть ли лучшие решения. Например:

str match {
    case "!!!" + rest => rest
    case _ =>
}

person Freewind    schedule 17.07.2011    source источник


Ответы (4)


val r = """^!!!(.*)""".r
val r(suffix) = "!!!rest of string"

Таким образом, suffix будет заполнен остатком строки, или будет выброшено scala.MatchError.

Другой вариант будет:

val r = """^(!!!){0,1}(.*)""".r
val r(prefix,suffix) = ...

И prefix либо будет соответствовать !!! или быть нулевым. например

(prefix, suffix) match {
   case(null, s) => "No prefix"
   case _ => "Prefix"
}

Приведенное выше немного сложнее, чем вам может понадобиться, но стоит взглянуть на мощь интеграции регулярных выражений в Scala.

person Brian Agnew    schedule 17.07.2011

Если это то, что вы делаете часто, вероятно, стоит создать экстрактор

object BangBangBangString{ 
   def unapply(str:String):Option[String]= {
       str match {
          case s if s.startsWith("!!!") => Some(s.stripPrefix("!!!"))
          case _ => None
       }
   }
}

Затем вы можете использовать экстрактор следующим образом

str match{
   case BangBangBangString(rest) => println(rest)
   case _ => println("Doesn't start with !!!")
}

или даже

for(BangBangBangString(rest)<-myStringList){
   println("rest")
}
person Dave Griffith    schedule 17.07.2011
comment
вместо создания одного пользовательского экстрактора вы можете создать класс, подобный экстрактору префиксов, с первым параметром аргумента startWith, а затем использовать его следующим образом: val BandBangBangString = new PrefixExtractor("!!!") - person Chad; 15.11.2014

Начиная с Scala 2.13, теперь можно сопоставить шаблон String с помощью отмена применения строкового интерполятора:

"!!!hello" match {
  case s"!!!$rest" => rest
  case _           => "oups"
}
// "hello"
person Xavier Guihot    schedule 30.04.2019

Хороший вопрос ! Даже я очень старался найти ответ.

Вот хорошая ссылка, где я нашел ответ

object _04MatchExpression_PatternGuards {
  def main(args: Array[String]): Unit = {
    val url: String = "Jan";

    val monthType = url match {
      case url if url.endsWith(".org")   => "Educational Websites";
      case url if url.endsWith(".com")   => "Commercial Websites";
      case url if url.endsWith(".co.in") => "Indian Websites"
      case _                             => "Unknow Input";
    }
  }
}
person Krishna Kumar    schedule 25.03.2017
comment
Это отвечает на другой вопрос. - person Robin Green; 08.06.2017