我经常将字符串与正则表达式匹配。在Java中:
java.util.regex.Pattern.compile( “\ W +”)。匹配( “this_is”)。匹配
哎哟。 Scala有很多选择。
"\\w+".r.pattern.matcher("this_is").matches
"this_is".matches("\\w+")
"\\w+".r unapplySeq "this_is" isDefined
val R = "\\w+".r; "this_is" match { case R() => true; case _ => false}
第一个与Java代码一样重要。
第二个问题是您无法提供已编译的模式("this_is".matches("\\w+".r")
)。 (这似乎是一种反模式,因为几乎每次有一个采用正则表达式进行编译的方法都存在需要正则表达式的重载。)
第三个问题是它滥用unapplySeq
因此是神秘的。
第四个在分解正则表达式的部分时很好,但是当你只想要一个布尔结果时,它太重了。
我是否错过了检查正则表达式匹配的简单方法?有没有定义String#matches(regex: Regex): Boolean
的原因?实际上,String#matches(uncompiled: String): Boolean
定义在哪里?
答案 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?