与Scala中的正则表达式匹配。

时间:2021-03-15 21:40:02

I fairly frequently match strings against regular expressions. In Java:

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

java.util.regex.Pattern.compile("\w+").matcher("this_is").matches

java.util.regex.Pattern.compile(“\ w +”).matcher .matches(“this_is”)

Ouch. Scala has many alternatives.

哎哟。Scala有许多选择。

  1. "\\w+".r.pattern.matcher("this_is").matches
  2. “\ \ w +”.r.pattern.matcher .matches(“this_is”)
  3. "this_is".matches("\\w+")
  4. “this_is”.matches(“\ \ w +”)
  5. "\\w+".r unapplySeq "this_is" isDefined
  6. “\ \ w +”。r unapplySeq isDefined“this_is”
  7. val R = "\\w+".r; "this_is" match { case R() => true; case _ => false}
  8. val R =“\ \ w +”R;“this_is”匹配{case R() => true;情况下_ = >假}

The first is just as heavy-weight as the Java code.

第一个和Java代码一样重。

The problem with the second is that you can't supply a compiled pattern ("this_is".matches("\\w+".r")). (This seems to be an anti-pattern since almost every time there is a method that takes a regex to compile there is an overload that takes a regex).

第二个问题是您不能提供一个已编译的模式(“this_is”.matches(“\w+”.r))。(这似乎是一个反模式,因为几乎每次有一个方法需要一个regex进行编译时,都会有一个重载需要一个regex)。

The problem with the third is that it abuses unapplySeq and thus is cryptic.

第三个的问题是它滥用不受欢迎的seq,因此是神秘的。

The fourth is great when decomposing parts of a regular expression, but is too heavy-weight when you only want a boolean result.

第四种方法在分解正则表达式的部分时很有用,但是当您只想要一个布尔结果时,这种方法就显得太笨重了。

Am I missing an easy way to check for matches against a regular expression? Is there a reason why String#matches(regex: Regex): Boolean is not defined? In fact, where is String#matches(uncompiled: String): Boolean defined?

我是否缺少一种简单的方法来检查与正则表达式匹配的匹配项?是否有一个原因解释为什么字符串#匹配(regex: regex):布尔值没有定义?实际上,字符串#matches(uncompile: String): Boolean定义在哪里?

4 个解决方案

#1


33  

You can define a pattern like this :

您可以这样定义一个模式:

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

findFirstIn will return Some[String] if it matches or else None.

如果匹配的话,findFirstIn将返回一些[String],否则就不返回。

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

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

You could even extract :

你甚至可以提取:

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

Finally, you can also use conventional String.matches method (and even recycle the previously defined Email Regexp :

最后,还可以使用常规字符串。匹配方法(甚至回收之前定义的电子邮件Regexp:

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

Hope this will help.

希望这将帮助。

#2


12  

I created a little "Pimp my Library" pattern for that problem. Maybe it'll help you out.

我为这个问题创建了一个“为我的库拉皮条”模式。也许它能帮到你。

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

Example of use

使用的例子

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

#3


4  

I usually use

我通常使用

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

but I think that is pretty awkward.

但我觉得这很尴尬。

#4


1  

Currently (Aug 2014, Scala 2.11) @David's reply tells the norm.

目前(2014年8月,Scala 2.11) @David的回复告诉我们这是正常的。

However, it seems the r."..." string interpolator may be on its way to help with this. See How to pattern match using regular expression in Scala?

然而,似乎r.“…”字符串插值器正在帮助解决这个问题。了解如何在Scala中使用正则表达式进行模式匹配吗?

#1


33  

You can define a pattern like this :

您可以这样定义一个模式:

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

findFirstIn will return Some[String] if it matches or else None.

如果匹配的话,findFirstIn将返回一些[String],否则就不返回。

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

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

You could even extract :

你甚至可以提取:

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

Finally, you can also use conventional String.matches method (and even recycle the previously defined Email Regexp :

最后,还可以使用常规字符串。匹配方法(甚至回收之前定义的电子邮件Regexp:

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

Hope this will help.

希望这将帮助。

#2


12  

I created a little "Pimp my Library" pattern for that problem. Maybe it'll help you out.

我为这个问题创建了一个“为我的库拉皮条”模式。也许它能帮到你。

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

Example of use

使用的例子

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

#3


4  

I usually use

我通常使用

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

but I think that is pretty awkward.

但我觉得这很尴尬。

#4


1  

Currently (Aug 2014, Scala 2.11) @David's reply tells the norm.

目前(2014年8月,Scala 2.11) @David的回复告诉我们这是正常的。

However, it seems the r."..." string interpolator may be on its way to help with this. See How to pattern match using regular expression in Scala?

然而,似乎r.“…”字符串插值器正在帮助解决这个问题。了解如何在Scala中使用正则表达式进行模式匹配吗?