Scala RegEx匹配失败,Java一个成功

时间:2016-03-22 13:06:32

标签: regex scala

在以下代码中,相同的模式在使用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 match abcde

     

Scala unapplySeq无

     

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

     

Scala不匹配

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

1 个答案:

答案 0 :(得分:5)

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

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

请参阅IDEONE demo

一些UnanchoredRegex reference

  

def unanchored: UnanchoredRegex

     

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

     

通常情况下,日期匹配的行为就好像模式用锚^pattern$括起来一样。

     

未锚定的正则表达式就好像这些锚被移除了一样。

     

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

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