Ben Nadel
On User Experience (UX) Design, JavaScript, ColdFusion, Node.js, Life, and Love.
I am the chief technical officer at InVision App, Inc - a prototyping and collaboration platform for designers, built by designers. I also rock out in JavaScript and ColdFusion 24x7.
Meanwhile on Twitter
Loading latest tweet...
Ben Nadel at the New York ColdFusion User Group (May. 2009) with: Gert Franz and Peter Bell

Java Matcher's QuoteReplacement() And Java 6 vs. Java 1.4.2

By Ben Nadel on
Tags: ColdFusion

Last week, on a very old post about the importance of escaping the "$" and "\" characters in appendReplacement() calls on the Java Pattern Matcher, Rob asked me why I wasn't just using the quoteReplacement() method. To be honest, I had never seen this method before. After a quick Google search, I found that this method will escape your replacement text in such a way that none of its characters will hold any special meaning. Typically, if you have a "$" in your replacement text, the Matcher is expecting it to be followed by a numeric value in reference to a captured group. The "\", on the other hand, is expected to be escaping characters. To stop the Matcher from performing such evaluation, you can pass your replacement text through the intermediary method call, quoteReplacement():

  • <!--- Store some text to search / replace. --->
  • <cfset text = "Let's make some cash money." />
  •  
  • <!--- Create the pattern we are going to search form. --->
  • <cfset pattern = createObject( "java", "java.util.regex.Pattern" )
  • .compile(
  • javaCast( "string", "money" )
  • )
  • />
  •  
  • <!--- Create our pattern matcher based on the target text. --->
  • <cfset matcher = pattern.matcher(
  • javaCast( "string", text )
  • ) />
  •  
  • <!--- Create a string buffer to hold our replacement text. --->
  • <cfset buffer = createObject( "java", "java.lang.StringBuffer" )
  • .init()
  • />
  •  
  • <!---
  • While we can find matches for "money", let's replace them
  • with the dollar sign.
  • --->
  • <cfloop condition="matcher.find()">
  •  
  • <!---
  • Replace with $. Notice that we are passing the
  • replacement text through the quoteReplacement()
  • method; this will escape special characters like
  • the "$" and "\".
  • --->
  • <cfset matcher.appendReplacement(
  • buffer,
  • matcher.quoteReplacement( javaCast( "string", "$" ) )
  • ) />
  •  
  • </cfloop>
  •  
  • <!--- Add the rest of the target string to the buffer. --->
  • <cfset matcher.appendTail( buffer ) />
  •  
  • <!--- Output the full replacement. --->
  • Result: #buffer.toString()#

As you can see, we are using a round-about way (for demo purposes) to replace the pattern, "money," with the string, "$". As we perform the replacement, we pass our replacement string through the quoteReplacement() method; and, when we run the above code, we get the following output:

Result: Let's make some cash $.

If we did not use quoteReplacement(), the Java Matcher would have expected a captured group reference and would have thrown the following error:

String index out of range: 1 null

This is a pretty convenient method and it makes me frustrated that I had never seen it before, especially since I've used the Matcher object so many times. At first, I thought it was just laziness in my exploration of the Matcher API; but, this morning, when I went to find it again, I realized what happened. As I started to write this post, I did a Google search for "java 2 matcher" in order to look at the method definition. This search got me to the Matcher documentation for Java 1.4.2 - the one I usually use. Low and behold, there was no quoteReplacement() method!

At first, I thought I was going crazy! How was it here last week and not this week? Then it dawned on me: ColdFusion now uses the newer JVM with Java 6. For the past few years, I've been explicitly searching for the Java 2 docs to make sure that the docs were the first Google search results. That was fine years ago when I started, but now, I'm 2 Java versions behind on my research and development! Shame shame! It looks like a good deal has been added to the API in the last few versions.

A big thanks to Rob for not only pointing out a useful Java Matcher method - quoteReplacement() - but also for making me realize how out of date my Java research actually was. Looks like it's time to catch up on what's new in the Java language.




Reader Comments

Just wanted to say thanks for posting this! I came across this today and it has been a great help :)

Thanks again!

Reply to this Comment

@Evan,

Cool - glad to help. Now, when I look things up on the Java docs, I always make it a point to Google "Java 6" when I do my searching.

Reply to this Comment

How crazy is that. I had the exact same issue and the quoteReplace solved the issue.
I myself also have never seen or heard about this method - seems that it was not needed with java 1.4.x but only with recent versions ie. >=1.5.

But thanx for painting a clear picture!

Reply to this Comment

@Morten,

My pleasure! It looks like when you Google for anything doc-related to Java, the 1.4.2 library seems to be the thing you get. Makes me wonder how much juiciness I've been missing out on!

Reply to this Comment

Post A Comment

You — Get Out Of My Dreams, Get Into My Comments
Live in the Now
Oops!
Comment Etiquette: Please do not post spam. Please keep the comments on-topic. Please do not post unrelated questions or large chunks of code. And, above all, please be nice to each other - we're trying to have a good conversation here.