Using .NET (dotnet) Regular Expressions In ColdFusion

Posted May 21, 2010 at 9:21 AM by Ben Nadel

Tags: ColdFusion

Since I am heading off to Scotch On The Rocks tomorrow, I figured this will pretty much be my last post for the next week or so. And, since Regular Expression Day 2010 ends in about a week, I thought I would try something that I have never tried before: loading and running a .NET (dotnet) regular expression inside of ColdFusion. Starting with ColdFusion 8, Adobe has added a .NET Integration Service to the ColdFusion installer that allows your ColdFusion code to access local and remote .NET (dotnet) assemblies (DLL files). Somewhat like its Java integration, ColdFusion does this by creating proxies to the actual .NET classes.

NOTE: As this is the first time I have played with .NET integration, please take any technical explanation with a grain of salt as it is likely flawed.

In ColdFusion, we have access to the POSIX regular expression engine and the underlying Java regular expression engine; so, why even bother using the .NET (dotnet) regular expression engine? For the most part, RegEx engines are the same; but, each flavor has its own specialized features. DotNet is no different. Unfortunately, I don't know anything about the .NET regular expression engine since I've never used it before. As such, I am going to flagrantly borrow from the flagrant badassery of RegEx guru, Steven Levithan.

In .NET regular expressions, you can use named collections to help keep track of patterns matched within a given string. Using a special notation, you can either push elements onto a named collection, pop elements off of a named collection, or check to see if the collection contains any remaining elements. I won't go into too much detail on how this works (as I just tried this myself for the first time), I'll just defer to Steve Levithan's blog post on this matter.

That said, let's use this depth-tracking regular expression construct inside ColdFusion using the .NET (dotnet) integration services. In .NET, the regular expression class, System.Text.RegularExpressions.Regex, is compiled within the System.dll assembly, which is, itself, contained within the root of the .NET framework (probably buried somewhere in your Windows folder - I had to search for mine). In the following demo, we're going to match patterns in which a string of "A" characters is followed by an equal number of "B" characters.

  • <!--- Store the path to the .NET framework. --->
  • <cfset frameworkDirectory = "C:\WINDOWS\Microsoft.NET\Framework\v2.0.50727\" />
  •  
  • <!---
  • Create an instance of the .NET RegEx CLASS definition. When
  • ColdFusion creates a .NET class, it works as if you are working
  • with a Java class - it gives you the static class until you call
  • the constrcutor or call a non-static method (at which point it
  • calls the default constructor if possible).
  • --->
  • <cfobject
  • name="pattern"
  • type="dotnet"
  • class="System.Text.RegularExpressions.Regex"
  • assembly="#frameworkDirectory#System.dll"
  • />
  •  
  •  
  • <!---
  • Create a .NET regular expression pattern. This uses
  • .NET's unique "depth" mechanism to track matching and
  • counter-matching patterns.
  •  
  • NOTE: I don't really know anything about this - I am borrowing
  • it from Steve Levithan:
  •  
  • http://blog.stevenlevithan.com/archives/balancing-groups
  • --->
  • <cfsavecontent variable="dotNetPattern">(?x)
  •  
  • ^
  •  
  • <!---
  • For each A that we encounter, push it onto the a stack with
  • the name "Counter".
  • --->
  • (?<Counter>A)+
  •  
  • <!---
  • For each B that we encounter, pop one item off of the stack
  • with the name "Counter."
  • --->
  • (?<-Counter>B)+
  •  
  • <!---
  • Once we have finished matching our A/B string, check to see
  • if there are any items remaining on the "Counter" stack. If
  • there are, apply an empty negative look-ahead (that will
  • always fail).
  • --->
  • (?(Counter)(?!))
  •  
  • $
  •  
  • </cfsavecontent>
  •  
  • <!---
  • Now that we have our .NET regular expression pattern, let's
  • instantiate and initialize our pattern object. Remember, the
  • init() method is how we call the constructor (same as with
  • the Java classes).
  • --->
  • <cfset pattern.init( dotNetPattern ) />
  •  
  •  
  • <!--- ----------------------------------------------------- --->
  • <!--- ----------------------------------------------------- --->
  •  
  •  
  • <!---
  • Now, let's check to see if variaous strings match against this
  • regular expression pattern.
  •  
  • NOTE: Only the fourth one *should* match.
  • --->
  • <cfoutput>
  •  
  • #pattern.isMatch( "AAA" )#<br />
  • #pattern.isMatch( "AAAB" )#<br />
  • #pattern.isMatch( "AAABB" )#<br />
  •  
  • <!--- Three and three. --->
  • #pattern.isMatch( "AAABBB" )#<br />
  •  
  • #pattern.isMatch( "AAABBBB" )#<br />
  • #pattern.isMatch( "AAABBBBB" )#<br />
  •  
  • </cfoutput>

Here, I am using the "?<Counter>", "?<-Counter>", and "?(Counter)" constructs to push, pop, and check the "Counter" stack respectively. Every time I hit an "A", I push and everytime I hit a "B", I pop. Then, at the end of the string, I make sure that the collection is empty (indicating an even number of push and pop actions).

When I run the above code, I get the following output:

NO
NO
NO
YES
NO
NO

As you can see, only the fourth string, "AAABBB," was a match for our .NET regular expression pattern. This is because the string was composed of three "A"s followed by an equal number of three "B"s.

In other regular expression engines, you can easily match three "A"s followed by three "B"s. What makes the .NET (dotnet) regular expression engine so exciting is that equal matching (3 and 3) doesn't have to have a predetermined length! I wonder what other kinds of gems are available in the .NET pattern classes? Special thanks to Steven Levithan for providing the actual RegEx understanding.



Reader Comments

May 21, 2010 at 10:41 AM // reply »
1 Comments

Thanks Ben for the wonderful tutorial.

But..I'm getting the following error!!

If a dll is specified in the assembly list, DotNetExtension must also be installed.

Any idea?


May 21, 2010 at 10:55 AM // reply »
11,238 Comments

@Kevin,

The .NET Integration stuff is actually an additional service that needs to be installed that runs along side the ColdFusion Application service. This way, you can turn it on and off without stopping ColdFusion.

It's one of the checkboxes in the ColdFusion installer. I never install it so last night when I wanted to play around with it, I actually ended up just uninstalling and re-installing ColdFusion (I couldn't figure out how to run an "update" for the installer without kicking into multi-instance mode).

I'm sure there is a way to just add on the .NET Integration stuff, but that goes beyond my understanding.


May 21, 2010 at 11:41 AM // reply »
3 Comments

No need to reinstall CF to get the .net integration services. On the CD or in the extras download is a CF8-DotNetIntegration.exe/ColdFusion_9_DotNetIntegration_WWE.exe to install the .net integration service into a existing installation.


May 21, 2010 at 11:45 AM // reply »
11,238 Comments

@Reto,

What happens if you got the installer from the website, so it's a single EXE file? Is the DotNet installer just put in the ColdFusion install directories?


May 21, 2010 at 12:02 PM // reply »
3 Comments

If you don't install the service with the ColdFusion installer you will not have the .net integration installer on your disk. You will need to take it from the cd or download. For CF8 download it was in a big extras.zip file, but the installer is just a single exe file. The cf8 download was just possible after a login with a purchased license on adobe.com. Don't know about CF9.

It's an Install Anywhere installer like for CF itself and looks the same. You can choose some options like path and installation mode:

Standalone;
You can install the .net integration services on a windows server where no ColdFusion is installed and connect from unix cf installation to use the .net feature.

with ColdFusion:
CF will be configured to use the new .net integration services installation.


May 21, 2010 at 12:06 PM // reply »
11,238 Comments

@Reto,

Hmm, I'll have to check out the extras.zip file on my home machine (at work, I am running in multi-instance mode, which I am still learning about).


Jun 4, 2010 at 8:31 PM // reply »
13 Comments

For anyone who is interested.

You can also just download the .NET integration services .exe from the adobe website.

http://www.adobe.com/support/coldfusion/downloads.html


Jun 7, 2010 at 9:46 AM // reply »
11,238 Comments

@Kevin,

Awesome!! Thanks for pointing this out. I know people have mentioned that it can be installed separately, but I had no idea where from. This is brilliant, thanks.


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
May 17, 2013 at 7:42 PM
HashKeyCopier - An AngularJS Utility Class For Merging Cached And Live Data
Ben - thanks so much for posting these Angular articles and findings, they've been a huge help towards learning one of the more 'complex' JavaScript frameworks out there (IMO). I have been using Angu ... read »
May 16, 2013 at 5:01 PM
UPDATE: Parsing CSV Data Files In ColdFusion With csvToArray()
Your code was the closest thing I've found to obtaining some direction for converting ISO fields to values that CF can translate properly. Thank you for posting! ... read »
May 15, 2013 at 10:37 PM
Very Simple Pusher And ColdFusion Powered Chat
hi id making plz easy ... read »
May 15, 2013 at 6:07 PM
Making SOAP Web Service Requests With ColdFusion And CFHTTP
Ben, you once again saved my bacon at work. Thank you, thank you, thank you! ... read »
May 15, 2013 at 4:15 PM
What If All User Interface (UI) Data Came In Reports?
@Josh, Thanks! @Ben, I definitely recommend the David West book "Object Thinking" I've been quoting from. It goes deeply into the philosophy and history of OO programming. His breadth ... read »
May 15, 2013 at 11:36 AM
Ask Ben: Print Part Of A Web Page With jQuery
I found this helpfull when you need to keep (refresh) the original parent page after closing the iframe child print dialog (Hoping you're not using a form at this time so it won't submit again): On ... read »
May 14, 2013 at 7:13 PM
What If All User Interface (UI) Data Came In Reports?
@Jonah, If there's any books you'd recommend on the subject of domain modelling, I'd love to hear it. I just downloaded the free PDF of "Domain Driven Design Quickly". Figured I'd give it ... read »
May 14, 2013 at 6:57 PM
The UX Of Prototyping: Low-Fidelity Is The New High-Fidelity
@Phillip, I'm not sure I follow what you mean? Are you saying that you looked at the list of widgets provided by the jQuery UI and let that be your style guide? ... read »
InVision App - Prototyping Made Beautiful With Prototyping Tools