String.replaceAll can take regular expression pattern arguments. Tried it with a Groovy script and had a compile error.
Ooops! Figured it out. In a slashy string, those using ‘/’ as terminators, the last character cannot be a ” since that will escape the terminator character, ‘/’. Thus,
def pattern = ~//
Will not compile. But, this:
def pattern = ~/${''}/
will. It is documented, I just kept missing it.
That is why it is used here:
println /c:abcd/.replaceAll((/${''}/),"/")
Alternatively, if your using Groovy 1.8* you can use the new $//$ slashy string:
println ( /c:abcd/.replaceAll(($//$),"/") )
or
println ( (/c:abcd/ =~ $//$).replaceAll("/") )
I was reading this blog post on the need to sometimes not use regular expression in Java: “Tip #5 Avoid RegEx When Unnecessary.”
To take the string “c:abcd” and convert it to “c:/a/b/c/d”, just do s.replace(”, ‘/’);. Don’t use regexp. And, I thought, it would be easy to still use regular expressions if Groovy were used, doesn’t the slashy string remove the backslash headache?
Example that gets compile error:
println "new is: " + /c:abcd/.replaceAll((//),"/")
C:temp>groovy test.groovy org.codehaus.groovy.control.MultipleCompilationErrorsException: startup failed: C:temptest.groovy: 2: expecting anything but ''n''; got it anyway @ line 2, column 58. bcd/.replaceAll((//),"/") ^ 1 error
I also tried using a compiled pattern, pat = ~//, but that did not work either, neither did a few other things. For example, this doesn’t work either:
println (/c:abcd/ =~ //).replaceAll("/")
The first set of parenthesis should have returned a Matcher object, and then the replaceAll called on it. Instead, we get:
C:temptest.groovy: 1: unexpected char: 0xFFFF @ line 1, column 47.
cd/ =~ //).replaceAll(“/”)
^
So I looked into the Groovy unit tests to see how they test the replaceAll function. Unit tests are sometimes a great way to learn how to use an API. True, some unit tests can be very obscure and complex.
The unit test I found was used the ${”} GString.
So, example that Compiles:
println "new is: " + /c:abcd/.replaceAll((/${''}/),"/")
C:temp>groovy test.groovy new is: c:/a/b/c/d
The command line inline script could then be:
C:temp>groovy -e "println "new is: " + /c:abcd/.replaceAll(/${''}/,"/")" new is: c:/a/b/c/d
Ok, so it was not easier in Groovy. Maybe a Groovy expert can make it as easy?
Now, why is it so hard?
Specs
Groovy version: 1.8.1
JVM: 1.6.0_25
OS: Windows 7 64bit
Further Reading
Ralph Towner — Tale of Saverio
As you’ve noticed, there is no way to end a slashy string with a backslash (since the slash is the only escapable character in a slashy string). If you need a long string with several backslashes, then your ${”} solution might be the best way. But if you only need one backslash, a single (or double) quote string with an escaped backslash, ”, it’s still the best solution. Either way it’s a string, and all strings (not just slashy strings) can be preceded with a ~ to make a regex pattern if needed.
Eric:
I didn’t know, makes sense though, that any string could be made a regex pattern with a ~.
Thanks for the comments.
P.S. Can’t really use “” as pattern, would need “\”. But, haven’t checked.