如何检查String是否与Scala中的Regex完全匹配?

mkn*_*ssl 80 regex scala

假设我有一个正则表达式模式我想匹配许多字符串.

val Digit = """\d""".r
Run Code Online (Sandbox Code Playgroud)

我只想检查给定的String是否与Regex完全匹配.在Scala中执行此操作的好方法是什么?

我知道我可以在正则表达式上进行模式匹配,但在这种情况下,这在语法上并不是很令人满意,因为我没有要提取的组:

scala> "5" match { case Digit() => true case _ => false }
res4: Boolean = true
Run Code Online (Sandbox Code Playgroud)

或者我可以回到基础Java模式:

scala> Digit.pattern.matcher("5").matches
res6: Boolean = true
Run Code Online (Sandbox Code Playgroud)

这也不优雅.

有更好的解决方案吗?

mkn*_*ssl 63

回答我自己的问题,我将使用"pimp my library pattern"

object RegexUtils {
  implicit class RichRegex(val underlying: Regex) extends AnyVal {
    def matches(s: String) = underlying.pattern.matcher(s).matches
  }
}
Run Code Online (Sandbox Code Playgroud)

并像这样使用它

import RegexUtils._
val Digit = """\d""".r
if (Digit matches "5") println("match")
else println("no match")
Run Code Online (Sandbox Code Playgroud)

除非有人提出更好的(标准)解决方案.

笔记

  • 我没有皮条客String来限制潜在副作用的范围.

  • unapplySeq 在这种情况下读得不太好.

  • @polygenelubricants 建议的内置“5”与“\\d”匹配怎么样? (2认同)
  • 数据与模式匹配,反之亦然.Regex上的scaladoc对于"匹配"缺少布尔值有很大帮助.就个人而言,我认为你已经换了一个漂亮的比赛,为了一个笨重的if-else.如果你不关心组,请使用`case r(_*)=>`. (2认同)
  • @JameelaHuq 访问这个问题的人们会对 2.13 感到满意,Regex 终于得到了匹配。https://github.com/scala/scala/pull/6521 (2认同)

pol*_*nts 56

我不太了解Scala,但看起来你可以做到:

"5".matches("\\d")
Run Code Online (Sandbox Code Playgroud)

参考

  • 嗯,这是有效的,但缺点是模式是在每次尝试匹配时编译的.出于性能原因,我想避免这种情况. (25认同)
  • 谢谢,这就是我要做的,看看我的回答.我希望回答一个人自己的问题是Stack Overflow上接受的行为...... Meta说它是...... (4认同)
  • @mkneissl:那么你的`.pattern.matcher(text).matches`就好了.如果Scala支持,您可以在某些实用工具方法或重载运算符或其他内容中隐藏详细程度. (3认同)
  • @ed.这甚至更慢,更残酷,为什么呢? (2认同)
  • 作为参考的链接已损坏 (2认同)

Vas*_*iuk 13

对于完整匹配,您可以使用unapplySeq.此方法尝试匹配目标(整个匹配)并返回匹配项.

scala> val Digit = """\d""".r
Digit: scala.util.matching.Regex = \d

scala> Digit unapplySeq "1"
res9: Option[List[String]] = Some(List())

scala> Digit unapplySeq "123"
res10: Option[List[String]] = None

scala> Digit unapplySeq "string"
res11: Option[List[String]] = None
Run Code Online (Sandbox Code Playgroud)

  • 虽然如此,unapply和unapplySeq的主要用法隐含在`match`块的`case`s中. (4认同)

Jac*_*ack 11

  """\d""".r.unapplySeq("5").isDefined            //> res1: Boolean = true
  """\d""".r.unapplySeq("a").isDefined            //> res2: Boolean = false
Run Code Online (Sandbox Code Playgroud)

  • 您最初的问题要求结果以“ true”或“ false”结尾,而不是“ Some”或“ None”。据我所知,isDefined在2年前不是库的一部分,但也许是。无论如何,我的回答不是重复的;-) (2认同)
  • 没问题;-) 我的错误,我应该解释为什么我在答案中使用 isDefined 。仅仅给出代码作为答案通常是一个坏主意,所以这是我的坏主意。 (2认同)