Scala 模式匹配中如何拆分列表?

Scala 模式匹配中如何拆分列表?,scala,list,pattern-matching,Scala,List,Pattern Matching,我有以下清单: val lst: List[Char] = //... 我想在模式匹配中使用它,如下所示: lst match { case firstPart :: '|' :: theRestOfTheList => //do something with them } 问题是firstPart被视为单个字符。但我希望它是第一个“|”之前列表的一部分 可以在Scala中以简洁的方式执行此操作吗?可以,使用自定义提取器 Scala REPL 警告:注意列表为空

我有以下清单:

val lst: List[Char] = //...
我想在模式匹配中使用它,如下所示:

lst match {
    case firstPart :: '|' :: theRestOfTheList =>
        //do something with them
}
问题是
firstPart
被视为单个字符。但我希望它是第一个
“|”之前列表的一部分


可以在Scala中以简洁的方式执行此操作吗?

可以,使用自定义提取器

Scala REPL 警告:注意列表为空的角落案例和其他案例

特殊语法

scala> :paste
// Entering paste mode (ctrl-D to finish)

object `|` {
    def unapply(list: List[Char]): Option[(List[Char], List[Char])] = {
      val (a, b) = list.splitAt(list.indexOf('|'))
      Some((a, b.tail))
    }
  }

// Exiting paste mode, now interpreting.

defined object $bar

scala> str match { case `|`(a, b) => println(s"$a  $b")}
List(f, o, o)  List(b, a, r)
听起来几乎就是您想要的,它将列表拆分为满足某个谓词的最长前缀和列表的其余部分:

val (firstPart, secondPart) = lst.span(_ != '|')

需要注意的是,
secondPart
将把
|
作为第一个元素,因此您的“real”第二部分是
secondPart.tail

如果您可以将字符串中的字符列表旋转,然后将其与正则表达式匹配,那么还有另一种方法可以做到这一点-我假设您拥有字符串中的原始字符列表。无论如何,解决方案如下:

val pattern = """(.*)\|(.*)""".r
lst.mkString match {
  case pattern(left, right) => // do something with left & right strings
  case _                    => // do something else
}

希望有帮助

也许
“hello | world”。split(\\\\”,2)match{case Array(start,tail)=>start+tail}
?@XavierGuihot实际上可以是一个解决方案!这是最简洁的吗?我怀疑可能还有其他原因……请注意,如果没有
|
存在,
secondPart
为空,因此
secondPart.tail
将失败。
val pattern = """(.*)\|(.*)""".r
lst.mkString match {
  case pattern(left, right) => // do something with left & right strings
  case _                    => // do something else
}