当替换字符串看起来像正则表达式时,scala regex replaceAllIn无法替换?

时间:2012-03-11 20:42:43

标签: regex scala

我很高兴地运行了一个正则表达式replaceAllIn很长一段时间,但当replacement字符串看起来像一个正则表达式时,遇到了问题。以下说明了问题(Scala 2.9.1-1)。请注意,真正的问题空间要复杂得多,因此使用更简单的解决方案的想法并不是真的可行(只是为了抢占不可避免的“你为什么不试试......”:D)

val data = "val re = \"\"\"^[^/]*://[^/]*/[^/]*$\"\"\".r"
val source = """here
LATEX_THING{abc}
there"""
val re = "LATEX_THING\\{abc\\}".r
println(re.replaceAllIn(source, data))

这会出现以下错误:

java.lang.IllegalArgumentException: Illegal group reference

如果我将data更改为简单的内容:

val data = "This will work"

然后一切都很好。

看起来replaceAllIn以某种方式查看第二个字符串并将其用作另一个RE来引用从第一个RE中记住的内容......但是文档对此没有任何说明。

我错过了什么?

编辑:好的,所以在查看java.util.regex.Matcher课程后,似乎预期的修复方法是:

re.replaceAllIn(source, java.util.regex.Matcher.quoteReplacement(data))

1 个答案:

答案 0 :(得分:10)

您需要转义替换字符串中的$

val data = "val re = \"\"\"^[^/]*://[^/]*/[^/]*\\$\"\"\".r"

否则,它被解释为组引用的开头(仅当$后跟一个或多个数字时才有效)。有关详细信息,请参阅the documentation了解java.util.regex.Matcher

  

替换字符串可能包含对捕获的子序列的引用   在上一场比赛中:$g的每次出现都将替换为   评估group(g) ...的结果可能是一个美元符号($)   作为替换字符串中的文字包含在其前面   反斜杠(\$)。

更新以解决您的评论并在上面进行编辑:是的,如果您不使用字符串文字,则可以使用Matcher.quoteReplacement(或者,如果您是,我猜,但是转义$似乎更容易在那种情况下),至少a chance quoteReplacement将来scala.util.matching.Regex将{{1}}作为一种方法。