我正在尝试将字符串文字与内部转义字符串的可能性进行匹配
到目前为止我得到的东西看起来像这样:
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"
有人可以向我解释我做错了什么,更重要的是为什么?
答案 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"
展开版本的工作速度要快得多,因为它以线性方式匹配字符串文字,而没有由正则表达式中的交替引起的过度回溯。
答案 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\""