Scala regex replaceAllIn can't replace when replace string looks like regular expression?

I ran Regex replaceAllIn quite some time, but ran into a problem when there was something like a regular expression in the replacement line. The problem is illustrated below (Scala 2.9.1-1). Please note that the real space of the problem is much more complicated, so the idea of ​​using a simpler solution is not really acceptable (just to preempt the inevitable "Why don't you try ...": D)

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

This results in the following error:

 java.lang.IllegalArgumentException: Illegal group reference 

If I changed data to something that was something simple:

 val data = "This will work" 

Then everything is fine.

It seems like replaceAllIn somehow looks into the second line and uses it as another RE to refer to what was remembered from the first RE ... but the docs don't say anything about it.

What am I missing?

edit : Okay, so looking at the java.util.regex.Matcher class, it seems like the supposed fix:

 re.replaceAllIn(source, java.util.regex.Matcher.quoteReplacement(data)) 
+7
source share
1 answer

You need to avoid $ in your replacement string:

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

Otherwise, it is interpreted as the beginning of a group link (which would only be valid if one or more digits followed $ ). See the documentation for java.util.regex.Matcher for more details:

A replacement string may contain references to subsequences captured during the previous match: each occurrence of $g will be replaced by the result of the group(g) evaluation ... The dollar sign ( $ ) can be included as a literal in the replacement string, preceded by a backslash ( \$ ).

Refresh to answer your comment and change above: Yes, you can use Matcher.quoteReplacement if you are not working with string literals (or, if you want, I think, but accelerating $ seems easier in this case), and there it is minimum chance that quoteReplacement will be available as a method on scala.util.matching.Regex in the future.

+9
source

All Articles