在以下代码中,使用 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 None
Scala findFirstIn Some(/oAuth.html?state=abcde)
Scala not matching
使用提取器语法时
val statePattern(se) = text
错误是 scala.MatchError
.是什么导致 Scala 正则表达式 unapplySeq 失败?
最佳答案
当你定义一个 Scala 模式时,它默认是 anchor 定的(=需要一个完整的字符串匹配),而你的 Java sj.find()
正在寻找字符串内任何地方的匹配项。添加 .unanchored
Scala 正则表达式也允许部分匹配:
val statePattern = statePatternString.r.unanchored
^^^^^^^^^^^
见 IDEONE demo
一些
UnanchoredRegex
reference :
def unanchored: UnanchoredRegex
Create a new Regex with the same pattern, but no requirement that the entire String matches in extractor patterns.
Normally, matching on date behaves as though the pattern were enclosed in anchors,
^pattern$
.The unanchored Regex behaves as though those anchors were removed.
Note that this method does not actually strip any matchers from the pattern.
替代解决方案 意味着添加
.*
在模式末尾,但请记住,默认情况下点不匹配换行符。如果解决方案应该是通用的,则 (?s)
应在模式开头指定 DOTALL 修饰符,以确保匹配具有潜在换行符序列的整个字符串。
关于regex - 使用 Scala 模式匹配时工作正则表达式失败,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36155207/