Using replaceAll with Groovy regular expressions

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

Similar Posts:

Creative Commons License
This work is licensed under a Creative Commons Attribution-NonCommercial-NoDerivs 3.0 Unported License.

4 thoughts on “Using replaceAll with Groovy regular expressions”

  1. 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.

  2. 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.

Leave a Reply

Your email address will not be published. Required fields are marked *