匹配Scala中的正则表达式

时间:2011-11-28 20:25:45

标签: regex scala

我经常将字符串与正则表达式匹配。在Java中:

java.util.regex.Pattern.compile( “\ W +”)。匹配( “this_is”)。匹配

哎哟。 Scala有很多选择。

  1. "\\w+".r.pattern.matcher("this_is").matches
  2. "this_is".matches("\\w+")
  3. "\\w+".r unapplySeq "this_is" isDefined
  4. val R = "\\w+".r; "this_is" match { case R() => true; case _ => false}
  5. 第一个与Java代码一样重要。

    第二个问题是您无法提供已编译的模式("this_is".matches("\\w+".r"))。 (这似乎是一种反模式,因为几乎每次有一个采用正则表达式进行编译的方法都存在需要正则表达式的重载。)

    第三个问题是它滥用unapplySeq因此是神秘的。

    第四个在分解正则表达式的部分时很好,但是当你只想要一个布尔结果时,它太重了。

    我是否错过了检查正则表达式匹配的简单方法?有没有定义String#matches(regex: Regex): Boolean的原因?实际上,String#matches(uncompiled: String): Boolean定义在哪里?

4 个答案:

答案 0 :(得分:33)

您可以定义这样的模式:

scala> val Email = """(\w+)@([\w\.]+)""".r

findFirstIn如果匹配则返回Some[String],否则返回None

scala> Email.findFirstIn("test@example.com")
res1: Option[String] = Some(test@example.com)

scala> Email.findFirstIn("test")
rest2: Option[String] = None

你甚至可以提取:

scala> val Email(name, domain) = "test@example.com"
name: String = test
domain: String = example.com

最后,您还可以使用传统的String.matches方法(甚至可以回收先前定义的Email Regexp

scala> "david@example.com".matches(Email.toString)
res6: Boolean = true

希望这会有所帮助。

答案 1 :(得分:14)

我为这个问题创建了一个“Pimp my Library”模式。也许它会帮助你。

import util.matching.Regex

object RegexUtils {
  class RichRegex(self: Regex) {
    def =~(s: String) = self.pattern.matcher(s).matches
  }
  implicit def regexToRichRegex(r: Regex) = new RichRegex(r)
}

使用示例

scala> import RegexUtils._
scala> """\w+""".r =~ "foo"
res12: Boolean = true

答案 2 :(得分:4)

我通常使用

val regex = "...".r
if (regex.findFirstIn(text).isDefined) ...

但我觉得这很尴尬。

答案 3 :(得分:1)

目前(2014年8月,Scala 2.11)@ David的回复告诉了标准。

然而,似乎r."..."字符串插值器可能正在帮助解决这个问题。见How to pattern match using regular expression in Scala?