The Regular Expression Multiline Flag In ColdFusion

Posted October 10, 2006 at 7:41 AM by Ben Nadel

Tags: ColdFusion

I am not sure how this applies directly to ColdFusion regular expressions and the use of REFind() and REReplace(). I have only tested this in the Java regular expressions that are available through ColdFusion (Once you go Java you can't go back). In standard regular expressions, the (^) symbol matches on the beginning of the target string and the ($) symbol matches on the end of the target string. To demonstrate this, let's store some text:

  • <!--- Store some text. --->
  • <cfsavecontent variable="strText">
  • Laughing as he snatched another plate from the stack,
  • Chalked his hands and monstrous back,
  • Said, Boy, stop lying and don't say you've forgotten!
  • Trouble with you is you aint been SQUATTIN!
  • </cfsavecontent>

Now, let's apply a regular expression that matches the entire string (^) to ($):

  • <!--- Match the entire string from start to end. --->
  • <cfset strText = strText.ReplaceAll(
  • "(^[\w\W]+$)",
  • "BEGIN::$1::END"
  • ) />

... we get the following output:

BEGIN::
Laughing as he snatched another plate from the stack,
Chalked his hands and monstrous back,
Said, Boy, stop lying and dont say you've forgotten!
Trouble with you is you aint been SQUATTIN!
::END

Notice that the (^) and ($) did indeed match the start and end of the string. Also, notice that we used a simple expressions [\w\W]+ to match every character in the string. Since \w is the word character and \W is the non-word character, we are definitely going to match every single character that we come across (remember your Ven diagrams).

Now, there is a regular expression flag, (?m), that tells the regular expression to match (^) at the beginning of EVERY line and to match ($) at the end of EVERY line. Let's run the same expression above except this time we will run a multiline flag on it.

  • <!--- Match the multiline string from start to end. --->
  • <cfset strText = strText.ReplaceAll(
  • "(?m)(^[\w\W]+$)",
  • "BEGIN::$1::END"
  • ) />

Notice that we start the expression with the (?m) multiline flag. Running this we get the following output:

BEGIN::
Laughing as he snatched another plate from the stack,
Chalked his hands and monstrous back,
Said, Boy, stop lying and dont say you've forgotten!
Trouble with you is you aint been SQUATTIN!
::END

But wait, isn't that the same exact thing as before? Yes. The problem with our example is that regular expressions are GREEDY. Our regular expression is trying to match as much as possible while still allowing matches on every line. To fix this, we must modify the expression to be non-greedy. To do so, we will add the (?) character after the (+) character:

  • <!---
  • Match the multiline string from start to end. Run
  • this expression as a non-greedy search.
  • --->
  • <cfset strText = strText.ReplaceAll(
  • "(?m)(^[\w\W]+?$)",
  • "BEGIN::$1::END"
  • ) />

This gives us the desired output:

BEGIN::
Laughing as he snatched another plate from the stack,::END
BEGIN::Chalked his hands and monstrous back,::END
BEGIN::Said, Boy, stop lying and don't say you've forgotten!::END
BEGIN::Trouble with you is you aint been SQUATTIN! ::END

Notice that the BEGIN and END strings are inserted at the beginning and the end of every line respectively.

Ok, so that might not look too sexy, but it is very useful. One of the places that I love to use something like this is when I am scripting database calls. Image that I had a delimited list of data in a data file like (we will simulate this in a CFSaveContent tag):

  • <!--- Simulate a delimited data file via CFSaveContent. ---->
  • <cfsavecontent variable="strText">
  • 1,Libby,9.0
  • 2,Anna,7.5
  • 3,Donna,6
  • 4,Sarah,9.5
  • </cfsavecontent>

We can run a multiline regular expression on this that will allow us to create a SQL statement for every line:

  • <!--- Generate SQL scripts. --->
  • <cfset strSQL = strText.ReplaceAll (
  • "(?m)^(\s)*([0-9]+),([^ ]+),([0-9.]+)$",
  • "UPDATE girl SET hotness = $4 WHERE id = $2;"
  • ) />

Here, we are using the (?m) multiline flag. We are also grouping the different data fields. This will give us the output:

UPDATE girl SET hotness = 9.0 WHERE id = 1;
UPDATE girl SET hotness = 7.5 WHERE id = 2;
UPDATE girl SET hotness = 6 WHERE id = 3;
UPDATE girl SET hotness = 9.5 WHERE id = 4;

Dump that in SQL Analyser or a CFQuery tag and we are good to go. Pretty cool huh?

If you are not using regular expressions, learn them. They are really awesome and so freakin' powerful. The multiline flag doesn't come alll that often, but it is great anytime to you want to treat each line as an individual entity. For more control, you can use this with the Java Pattern / Matcher to handle each line on it's own.




Reader Comments

Feb 2, 2007 at 11:09 PM // reply »
172 Comments

Note that anytime, even when using multi-line mode, you should be able to use \A to match the start of the string and \z to match the end. Also note that I haven't tested those operators in ColdFusion, so here's hoping it's not another feature ColdFusion left off the regex support list.


Feb 3, 2007 at 7:53 PM // reply »
11,314 Comments

Just so we're on the same page, is the \A and \z stuff equivalent to ^ and $ when multi-line matching is NOT enabled? And, if I understand what you are saying, then even if you are doing multi-line matching, \A and \z will still match the very beginning / end of the ENTIRE string.

If that is the case, awesome. I was wondering what the heck those were for. I should just learn by now that none of this stuff is excess, that if I don't see the difference between two things, I probably am not understanding it.


Feb 3, 2007 at 9:52 PM // reply »
172 Comments

[If that is the case, awesome.]

That is the case, and it is indeed quite nifty. Another related (but not nearly as useful, IMO) operator is \Z (uppercase z), which matches at the end of the string and never before line breaks, except for the very last line break if the string ends with a line break. (Whoever thought up that operator had too much free time.)


Jan 10, 2008 at 7:01 PM // reply »
172 Comments

Hi again, Ben. I've recently written up a post on the nitty-gritty of the the regex singleline and multiline flags (and why the names can be highly misleading) at http://blog.stevenlevithan.com/archives/singleline-multiline-confusing . Just referencing it here for other people who find this, since I assume you're fairly familiar with how these modes work.


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
Ben Nadel's Company - Epicenter Consulting Recent Blog Comments
Jun 18, 2013 at 3:39 PM
Experimenting With The Amazon Simple Storage Service (S3) API Using ColdFusion
Hi Ben, THANKS! While not bleeding edge, it is new to me & I like learning new things every day! ... read »
Jun 18, 2013 at 12:30 PM
Disabling Auto-Correct And Auto-Capitalize Features On iPhone Inputs
Also spellcheck="false" should be mentioned as part of html5 specs ... read »
Jun 18, 2013 at 8:40 AM
Using Named Functions Within Self-Executing Function Blocks In Javascript
Hi Ben, you forgot to mention the most important thing for named self-executing functions - they can be referenced by name ONLY inside their execution context (which is parens in this case), it mean ... read »
dee
Jun 18, 2013 at 7:01 AM
My Safari Browser SQLite Database Hello World Example
hai ben, this program is really good i could understand the concept but i dint know how to save it and how to open it as you have done in the video can u give that details pls ... read »
Jun 18, 2013 at 6:04 AM
Clearing Inline CSS Properties With jQuery
Thanks a lot for for post! It helped me a lot... after being stuck since 24 hrs.. found solution from your post. Thanks again! ... read »
Jun 18, 2013 at 2:31 AM
SOTR 2013 - The Best Conference I Never Went To
I keep watching it, should keep me happily distracted until SotR14 ;) ... read »
Jun 17, 2013 at 9:45 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, As I was reading what you wrote, it occurred to me that maybe I do something similar to that in some of my client-side code. In an application I'm working on, there are a bunch of unrelated ... read »
Jun 17, 2013 at 9:36 PM
Object Thinking By David West
@Jonah, Please, don't feel bad at all. I appreciate all that you have contributed to the conversation. And, the more points of view I get, the more confident I am that I will some day, some how und ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools