Scala 字符串的不区分大小写模式匹配

Scala 字符串的不区分大小写模式匹配,scala,Scala,这是区分大小写的匹配。如何编写不区分大小写的匹配?我知道我可以为每个分支调用toLowerCase,但我需要更优雅的解决方案。基本方法: 您可以使用模式保护和正则表达式 match (str) { case "String1" => ??? case "String2" => ??? } 复杂的方法: 使用字符串插值隐式和正则表达式 str match { case s if s matches "(?i)String1" => 1 case s if s match

这是区分大小写的匹配。如何编写不区分大小写的匹配?我知道我可以为每个分支调用toLowerCase,但我需要更优雅的解决方案。

基本方法:

您可以使用模式保护正则表达式

match (str) {
  case "String1" => ???
  case "String2" => ???
}
复杂的方法:

使用字符串插值隐式正则表达式

str match {
case s if s matches "(?i)String1" => 1
case s if s matches "(?i)String2" => 2
case _ => 0
}
REPL中的一些示例用法:

implicit class CaseInsensitiveRegex(sc: StringContext) {
  def ci = ( "(?i)" + sc.parts.mkString ).r
}

def doStringMatch(str: String) = str match {
  case ci"String1" => 1
  case ci"String2" => 2
  case _ => 0
}

另一种不依赖正则表达式或插值器的方法:

scala> doStringMatch("StRINg1")
res5: Int = 1

scala> doStringMatch("sTring2")
res8: Int = 2
下面是使用插值器但不使用正则表达式的另一种方法:

 implicit class StringExtensions(val s: String) extends AnyVal {
    def insensitive = new {
      def unapply(other: String) = s.equalsIgnoreCase(other)
    }
  }

  val test1 = "Bye".insensitive
  val test2 = "HELLo".insensitive

  "Hello" match {
    case test1() => println("bad!")
    case test2() => println("sweet!")
    case _ => println("fail!")
  }
上述内容也可用于案例类别内部的模式匹配,例如:

  implicit class StringInterpolations(sc: StringContext) {
    def ci = new {
      def unapply(other: String) = sc.parts.mkString.equalsIgnoreCase(other)
    }
  }

  "Hello" match {
    case ci"Bye" => println("bad!")
    case ci"HELLO" => println("sweet!")
    case _ => println("fail!")
  }
简易解决方案:

case class Dog(name: String)

val fido = Dog("FIDO")

fido match {
  case Dog(ci"fido") => "woof"    
  case _ => "meow :("    
}

str
上调用小写,这将避免重复(显然,所有的大小写选项都需要小写)。大小写选项是常量,我不能modify@orionll你不能重写整个匹配语句,对吗?(例如,用regexp匹配器替换普通字符串)除了修改字符串常量之外,我可以做任何事情。您提到了每个分支的
toLowerCase
,但为什么不在
str
toLowerCase
?不需要隐式等(如下)有一个函数
String.equalsIgnoreCase
。不需要正则表达式.Ha,只是想说明.map(=>“x”)是另一个示例的一部分,这里不需要。它将根据插入字符串的最后一部分添加一个命名的捕获组,并在末尾添加一个x。我调整了示例并删除了未使用的部分。有没有一种方法可以在执行模式匹配时将多个不区分大小写的字符串添加到一个大小写中?这不起作用,但如果这样做有效,那就太酷了!如果你能做到的话,你能详细说明一下吗?@user247077:对不起,我直接在答题框里写了一个字,而且打错了。现在试一试-我自己验证了这一点。对于那些像我一样感到疑惑的人来说,这两个示例都依赖于unapply的语法,其中返回值是布尔值(另外两个是返回值是
Opt[T]
,或者
Opt[Seq[T]]
。第二个示例语法可能与s“xyz$a”中的语法相似一种语法。似乎比其他方法简单得多。我没有注意到任何缺点吗?一个可能的缺点是,如果不注意区域设置,您可能会在大小写转换方面遇到问题。例如,根据区域设置,我可能会转换为I或İ。这应该是公认的答案。toLowerCase也可以工作。t他的方法适用于字符串文本。但当您与其他地方定义的常量(例如case MyConstant=>…)进行匹配时,这种方法就会出现问题。
val str = "string1"

str toUpperCase match (str) {
  case "STRING1" => ???
  case "STRING2" => ???
}