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

Posted January 25, 2010 at 8:36 AM by Ben Nadel

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

Jan 25, 2010 at 9:05 AM // reply »
145 Comments

More blog fodder!


Jan 25, 2010 at 9:06 AM // reply »
10,640 Comments

@Lola,

I hope so :)


Rob
Jan 25, 2010 at 5:20 PM // reply »
3 Comments

/thumbsup


Jan 25, 2010 at 5:21 PM // reply »
10,640 Comments

@Rob,

Thanks again Rob :)


Sep 23, 2010 at 12:37 AM // reply »
1 Comments

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

Thanks again!


Sep 23, 2010 at 2:30 PM // reply »
10,640 Comments

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


Feb 23, 2011 at 8:07 AM // reply »
1 Comments

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!


Feb 23, 2011 at 10:38 AM // reply »
10,640 Comments

@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!


Post A Comment

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.

Please review the following issues:

Author Name:


Author Email:

Author Website:

Comment:

Supported HTML tags for formatting: <strong>bold</strong>   <em>italic</em>   <code>code</code>







  • Help Wanted - Find Your Next ColdFusion Job
InVision App - Prototyping Made Beautiful With Prototyping Tools Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Feb 12, 2012 at 3:37 AM
Learning ColdFusion 8: CFImage Part III - Watermarks And Transparency
Hi Ben, Just to ask currently it is placed bottom right corner, if i need to replace the same rendered image on the bottom left side or in the bottom center, how that can be calculated. bottom ce ... read »
Feb 11, 2012 at 9:29 PM
Use jQuery's SlideDown() With Fixed-Width Elements To Prevent Jumping
I can't say how glad I am that I found your post. Thank you very much. ... read »
Feb 10, 2012 at 7:21 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
Update! Instead of $(eval(options.insertAfter)).after(data['insertData']); I now use: var ajaxNode = document.createElement('span'); var parent = $(eval(options.insertAfter))[0].parentNode; ... read »
Feb 10, 2012 at 6:18 PM
jQuery AJAX Strips Script Tags And Inserts Them After Parent-Most Elements
encountered this same, what I consider, jQuery bug last week. I'm building a site in which I load some content via AJAX. This content contains Linkedin share button placeholders which Linkedin API ne ... read »
Feb 10, 2012 at 11:30 AM
Cross-Origin Resource Sharing (CORS) AJAX Requests Between jQuery And Node.js
After you understand the concepts here, this is an awesome cheatsheet for enabling CORS in just about anything http://enable-cors.org/ ... read »
JM
Feb 10, 2012 at 9:10 AM
My Safari Browser SQLite Database Hello World Example
@Amy, Here is a very good tutorial on how to use JOIN: http://www.sqltutorial.org/sqljoin-innerjoin.aspx ... read »
Feb 10, 2012 at 4:42 AM
Building A Twitter-Inspired RESTful API Architecture In ColdFusion
This is great, very useful Ben. I spotted a small typo in the api.cgm listing: <cfthrow type="Unauthroized" /> Cheers Stefan ... read »
Feb 9, 2012 at 10:35 PM
CFDirectory Filtering Uses Pipe Character For Multiple Filters (Thanks Steve Withington)
I was wondering if there would be a filter you could apply so that you got everything but what you included in the filter. As in show me all docs that are not a .pdf. ... read »