无法匹配正则表达式中的字符串文字

时间:2016-03-28 19:01:17

标签: regex scala pattern-matching

我正在尝试将字符串文字与内部转义字符串的可能性进行匹配

到目前为止我得到的东西看起来像这样:

def matchStringLiteral(input: String) = {
  val strLit = """(\"(\\.|[^"])*\")""".r
  input match {
    case strLit(s) => s"matched literal $s"
    case _ => "didn't match anything"
  }
}

除非我尝试使用它,否则:

val str = "\"welcome to \\\"GenericWebsiteName.com\\\"\""
println(matchStringLiteral(str))

尽管在Regex101

上工作正常,但仍打印"didn't match anything"

有人可以向我解释我做错了什么,更重要的是为什么

2 个答案:

答案 0 :(得分:3)

问题是您在模式中定义了2个捕获组(("(\\.|[^"])*")中的2个unescape括号),然后在case strLit(s)中声明一个参数 - Scala期望 2 2个捕获值的参数。

因此,要么定义2个参数:

case strLit(s1, s2) => s"matched literal. Group 1: $s1\nGroup 2: $s2"

请参阅IDEONE demo

或者 - 最好 - 将an unrolled version of your regex与非捕获组一起使用,没有任何捕获组:

val strLit = """"[^"\\]*(?:\\.[^"\\]*)*"""".r
...
case strLit() => s"matched literal $input"

请参阅another IDEONE demo

展开版本的工作速度要快得多,因为它以线性方式匹配字符串文字,而没有由正则表达式中的交替引起的过度回溯。

答案 1 :(得分:0)

这有效

"""(\"(\\.|[^"])*\")""".r.findFirstMatchIn("\"welcome to \\\"GenericWebsiteName.com\\\"\"")
res3: Option[scala.util.matching.Regex.Match] = Some("welcome to \"GenericWebsiteName.com\"")

我认为问题是,当你想要像这样模式匹配时,你的正则表达式需要有一个组(不允许嵌套组)。当你在里面使用非捕获组时,它可以工作。

def matchStringLiteral(input: String) = {
  val strLit = """(\"(?:\\.|[^"])*\")""".r
  input match {
    case strLit(s) => s"matched literal $s"
    case _ => "didn't match anything"
  }
}

scala> matchStringLiteral(str)
res9: String = matched literal "welcome to \"GenericWebsiteName.com\""