Scala,模式匹配,字符串

5
有没有办法在Scala中像这样匹配字符串:
  def matcher(arg: String) : Expr = {
    case left :: '*' :: right => new Binary("*", left, right)
    case left :: '+' :: right => new Binary("+", left, right)
  }

左边和右边的类型都是字符串(String)吗?


左边和右边的长度是固定的吗? - Andreas Neumann
3个回答

9

您可以通过匹配正则表达式来实现目标。

trait Expr

case class Binary(op: String, leftOperand: String, rightOperand: String) extends Expr

val mulPattern = "(\\d*)\\*(\\d*)".r
val addPattern = "(\\d*)\\+(\\d*)".r

def matcher(arg: String) : Expr = {
  arg match {
    case mulPattern(left, right) => new Binary("*", left, right)
    case addPattern(left, right) => new Binary("+", left, right)
  }
}

def main(args: Array[String]): Unit = {
  println(matcher("1+2")) // Binary("+", "1", "2")
  println(matcher("3*4")) // Binary("*", "3", "4")
} 

1
可以创建一个方法来生成这些模式,可能像这样:def binRegex(symbol: Char) = raw"""([^$symbol]+)[$symbol]([^$symbol]+)""".r - Łukasz
谢谢您的回答,先生! - DoSofRedRiver

2

我不这么认为。

如果你将String转换成ListVector类型的Char,然后使用mkString方法反转结果,可能可以做到。但是我还没有想出来具体的方法。

然而,在我看来,正则表达式更加简洁易读:

trait Expr

case class Binary(op: String, left: String, right: String) extends Expr

val Expression = """(.*?)\s*([+-\/\^\*])\s*(.*)""".r
def matcher(arg: String) : Expr = arg match {
  case Expression(left, op, right) => new Binary(op, left, right)
}

val test = matcher("a + b")
val test2 = matcher("a * b")

1
您也可以使用提取器来完成这个操作:

object Mult {
  def unapply(x: String): Option[(String, String)] = x.split("\\*") match {
    case Array(a: String, b: String) => Some(a -> b)
    case _ => None
  }
}

object Add {
  def unapply(x: String): Option[(String, String)] = x.split("\\+") match {
    case Array(a: String, b: String) => Some(a -> b)
    case _ => None
  }
}

def matcher(arg: String) = arg match {
    case Mult(left, right) => Binary("*", left, right)
    case Add(left, right) => Binary("+", left, right)
    case _ => println("not matched")
 }

你可能还想为每个提取器实现apply方法,如下所示:
def apply(l: String, r: String) = s"$l*$r"

但这不是强制性的。

似乎你的解决方案最适合我了,谢谢! - DoSofRedRiver

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接