0

使用 Scala 的模式匹配,我不仅想确认两个Strings 相等,还想确认 a 是否以String开头、结尾或包含在另一个等中。

我尝试了案例类和提取器对象,都没有给我一个简洁的解决方案。所以我想出的解决方案如下所示:

class StrMatches(private val str: Option[String]) {

  def ^(prefix: String) = str.exists(_.startsWith(prefix))

  def §(suffix: String) = str.exists(_.endsWith(suffix))

  def %(infix: String) = str.exists(_.contains(infix))

  def ~(approx: String) = str.exists(_.equalsIgnoreCase(approx))

  def /(regex: scala.util.matching.Regex) = str.collect({ case regex() => true }).isDefined

  def °(len: Int) = str.exists(_.length == len)

  def °°(len: (Int, Int)) = str.exists(a => a.length >= len._1 && a.length <= len._2)

  def `\\s*` = str.exists(_.trim.isEmpty)

  override def toString = str.mkString

}

object StrMatches {

  implicit def apply(x: Str) = new StrMatches(x)

  def unapply(x: StrMatches) = x.str

  implicit def unwrap(x: StrMatches) = x.toString

}

使用StrMatches该类的客户端可能如下所示:

object TestApp extends App {
  val str = "foobar"
  val strMatches = StrMatches(str)
  if (strMatches ^ "foo") {
    println(strMatches)
  }
  if (strMatches § "bar") {
    println(strMatches)
  }
  if (strMatches % "ob") {
    println(strMatches)
  }
}

与写作相反:

object TestApp extends App {
  val str: String = null // Just as an illustration for Scala interfacing Java.
  if (str != null) {
    if (str.startsWith("foo")) {
      println(str)
    }
    if (strMatches.endsWith("bar")) {
      println(str)
    }
    if (strMatches.contains("ob")) {
      println(strMatches)
    }
  }
}

你会想出什么样的解决方案?

4

1 回答 1

0

你可以使用正则表达式。然后你可以使用模式匹配(我认为这是你问题的初衷):

object TestApp extends App {
    val str = "foobar"

    val StartsWithFooRE = """^foo.*""".r
    val EndsWithBarRE = """.*bar$""".r
    val ContainsBoRE = """.*bo.*""".r

    str match {
        case StartsWithFooRE() => println(str)
        case EndsWithBarRE() => println(str)
        case ContainsBoRE() => println(str)
        case _ =>
    }
}

为了更方便,您可以定义一个带有工厂方法的对象来构造正则表达式。但是,由于模式匹配的工作原理,您仍然必须在匹配之外定义表达式:

import scala.util.matching.Regex

object RegexFactory {
    def startsWith(str: String) = new Regex("^%s.*" format str)
    def endsWith(str: String) = new Regex(".*%s$" format str)
    def contains(str: String) = new Regex(".*%s.*" format str)
}


object TestApp extends App {    
    val str = "foobar"

    import RegexFactory._

    val StartsWithFooRE = startsWith("foo")
    val EndsWithBarRE = endsWith("bar")
    val ContainsBoRE = contains("bo")

    str match {
        case StartsWithFooRE() => println(str)
        case EndsWithBarRE() => println(str)
        case ContainsBoRE() => println(str)
        case _ =>
    }
}
于 2011-09-11T01:55:20.310 回答