• Post Reply Bookmark Topic Watch Topic
  • New Topic
programming forums Java Mobile Certification Databases Caching Books Engineering Micro Controllers OS Languages Paradigms IDEs Build Tools Frameworks Application Servers Open Source This Site Careers Other Pie Elite all forums
this forum made possible by our volunteer staff, including ...
Marshals:
  • Devaka Cooray
  • Campbell Ritchie
  • Tim Cooke
  • Ron McLeod
  • Paul Clapham
Sheriffs:
  • Liutauras Vilda
  • Jeanne Boyarsky
  • paul wheaton
Saloon Keepers:
  • Tim Holloway
Bartenders:

Pattern ReplaceAll issue (Illegal Group exception)

 
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Fiddling with regular expressions...

This line:

aMatcher.replaceAll(value);

is throwing the following mess, pasted below.

The crux is that value contains a "$". What is the proper way to escape this? I tried preceeding it with


(which is funny) but no dice.


didn't seem to help either. Ideas?

-=-=-=-=-=-

java.lang.IllegalArgumentException: Illegal group reference
at java.util.regex.Matcher.appendReplacement(Unknown Source)
at java.util.regex.Matcher.replaceAll(Unknown Source)
at com.comdata.svs.util.SkeletonRplc.subsLine(SkeletonRplc.java:158)
at com.comdata.svs.util.SkeletonRplcTest.testSubsLine6(SkeletonRplcTest.java:63)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source)
at java.lang.reflect.Method.invoke(Unknown Source)
at junit.framework.TestCase.runTest(TestCase.java:154)
at junit.framework.TestCase.runBare(TestCase.java:127)
at junit.framework.TestResult$1.protect(TestResult.java:106)
at junit.framework.TestResult.runProtected(TestResult.java:124)
at junit.framework.TestResult.run(TestResult.java:109)
at junit.framework.TestCase.run(TestCase.java:118)
at junit.framework.TestSuite.runTest(TestSuite.java:208)
at junit.framework.TestSuite.run(TestSuite.java:203)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.runTests(RemoteTestRunner.java:478)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.run(RemoteTestRunner.java:344)
at org.eclipse.jdt.internal.junit.runner.RemoteTestRunner.main(RemoteTestRunner.java:196)
 
Tony Smith
Ranch Hand
Posts: 77
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
Ok, after thinking about it, it seems one issue is that I improperly escaped the string.

Instead of


I think I really need


So that the end result actually has the backslashes embedded within it.

But this is stinky. Is there a more elegant way?
 
Ranch Hand
Posts: 3061
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator

Originally posted by Tony Smith:
Ok, after thinking about it, it seems one issue is that I improperly escaped the string.

Instead of


I think I really need


So that the end result actually has the backslashes embedded within it.

But this is stinky. Is there a more elegant way?


No, I don't think there is a more elegant way of escaping (pun not intended) Escape Character Hell (TM). Well, you could read the regex from a file which will presumably negate the need for some of the escape characters. The solution you found actually makes sense if you think through all the stages where escape characters are required (i.e. the Java compiler and then the regex engine).

Layne
 
Ranch Hand
Posts: 262
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
If you're running Java 5, you can use Matcher's new quoteReplacement method. If you're rolling your own, you should probably escape backslashes as well as dollar signs:
 
Wanderer
Posts: 18671
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
I believe Matcher.quoteReplacement() is for escaping the replacement string (the second argument in replaceAll()). To escape the target string (the first argument), use Pattern.quote() instead. Or you can use the new replace(CharSequence, CharSequence) in String, which treats both arguments literally (I think).

Ugh. It's nice that they finally provided these methods, but putting them arbitrarily in different classes like that -ugh. And I don't know how anyone is supposed to guess that replaceAll() uses regexes, but replace() does not. Very annoying.
 
Alan Moore
Ranch Hand
Posts: 262
  • Mark post as helpful
  • send pies
    Number of slices to send:
    Optional 'thank-you' note:
  • Quote
  • Report post to moderator
The replacement string is what Tony was talking about--second argument to String#replaceAll, first (only) argument to Matcher#replaceAll.

The biggest problem I have with the API is the fact that the docs for String#replaceAll and String#replaceFirst don't even mention that there's anything special about the second argument. You have to follow a link to the corresponding Matcher methods just to learn that some characters have special meaning, and if you want to know how they actually work you have to follow another link, to the appendReplacement method. It's almost like they're trying to keep it secret.
 
I am going to test your electrical conductivity with this tiny ad:
Paul Wheaton's 16th Kickstarter: Gardening playing cards for gardeners and homesteaders
https://coderanch.com/t/889615/Paul-Wheaton-Kickstarter-Gardening-playing
reply
    Bookmark Topic Watch Topic
  • New Topic