【问题标题】:Scala, pattern matching, stringsScala,模式匹配,字符串
【发布时间】:2016-01-08 07:26:42
【问题描述】:

有没有办法像这样在scala中匹配字符串:

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

其中 left 和 right 是 String 类型的?

【问题讨论】:

  • 左右是固定长度吗?

标签: string scala pattern-matching


【解决方案1】:

我不这么认为。

如果您将String 转换为CharListVector,然后使用mkString 还原结果,您也许可以做到这一点。但我一直想不出什么。

但是,imo,正则表达式会更简洁易读:

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

【讨论】:

    【解决方案2】:

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

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

    【讨论】:

    • 可以创建一种方法来创建这些模式,可能是这样的:def binRegex(symbol: Char) = raw"""([^$symbol]+)[$symbol]([^$symbol]+)""".r
    • 谢谢您的回答,先生!
    【解决方案3】:

    您也可以使用提取器来做到这一点:

    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"
    

    但这不是强制性的

    【讨论】:

    • 看来您的解决方案最适合我,谢谢!
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-02-05
    • 2018-05-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多