【问题标题】:Working regex fails when using Scala pattern matching使用 Scala 模式匹配时,工作正则表达式失败
【发布时间】:2019-11-01 02:56:36
【问题描述】:

在下面的代码中,当使用 Java API 时,相同的模式匹配,但在使用 Scala 模式匹配时不匹配。

import java.util.regex.Pattern

object Main extends App {
  val text = "/oAuth.html?state=abcde&code=hfjksdhfrufhjjfkdjfkds"

  val statePatternString = """\/.*\?.*state=([^&\?]*)"""
  val statePattern = statePatternString.r
  val statePatternJ = Pattern.compile(statePatternString)

  val sj = statePatternJ.matcher(text)
  val sjMatch = if (sj.find()) sj.group(1) else ""
  println(s"Java match $sjMatch")

  val ss = statePattern.unapplySeq(text)
  println(s"Scala unapplySeq $ss")
  val sm = statePattern.findFirstIn(text)
  println(s"Scala findFirstIn $sm")

  text match {
    case statePattern(s) =>
      println(s"Scala matching $s")
    case _ =>
      println("Scala not matching")
  }

}

应用输出是:

Java 匹配 abcde

Scala unapplySeq 无

Scala findFirstIn Some(/oAuth.html?state=abcde)

Scala 不匹配

使用提取器语法val statePattern(se) = text 时,错误为scala.MatchError

是什么导致 Scala 正则表达式 unapplySeq 失败?

【问题讨论】:

  • 你能解释一下你想匹配什么吗?
  • 如果问题和/或接受的答案可以在内容的某处包含“MatchError”,这将很有帮助。对 Java 的引用与对发生这种情况时生成的 scala.MatchError 异常的引用相结合,使得当来自仅 Scala 的上下文时很难搜索到该条目。这是我因未能找到它而最终产生的问题。 stackoverflow.com/q/66392638/501113

标签: regex scala


【解决方案1】:

当您定义 Scala 模式时,默认情况下它是锚定的(=需要完整的字符串匹配),而您的 Java sj.find() 正在字符串内的任何位置寻找匹配。为 Scala 正则表达式添加 .unanchored 以允许部分匹配:

val statePattern = statePatternString.r.unanchored
                                       ^^^^^^^^^^^

IDEONE demo

一些UnanchoredRegex reference:

def unanchored: UnanchoredRegex

使用相同的模式创建一个新的正则表达式,但不要求整个字符串在提取器模式中匹配

通常,日期匹配的行为就像模式被包含在锚点中一样,^pattern$

未锚定的正则表达式的行为就像那些锚已被删除。

请注意,此方法实际上不会从模式中删除任何匹配器。

另一种解决方案意味着在模式末尾添加 .*,但请记住,默认情况下点与换行符不匹配。如果解决方案应该是通用的,则应在模式的开头指定 (?s) DOTALL 修饰符,以确保匹配具有潜在换行符序列的整个字符串。

【讨论】:

  • 非常感谢,这很有道理。另一种解决方案(在我的情况下我更喜欢)它在末尾提供一个 .* 以匹配字符串的其余部分。
  • 是的,它几乎等效。如果您使用.*,请不要忘记在模式开头添加(?s) DOTALL 修饰符,以便. 可以匹配换行符(如果字符串有换行符)。然后,这将是一个通用的解决方案。我将此注释添加到答案中。
  • 在我的情况下,我匹配的是 URL,因此对我来说没有换行符,但为了完整起见,最好提及它。
猜你喜欢
  • 1970-01-01
  • 2020-10-15
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-11-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多