Following are some UDFs I wrote recently to make using regexes in ColdFusion a bit easier. The biggest deal here is my reMatch()
function.
reMatch()
, in its most basic usage, is similar to JavaScript's String.prototype.match()
method. Compare getting the first number in a string using reMatch()
vs. built-in ColdFusion functions:
- reMatch:
<cfset num = reMatch("\d+", string) />
- reReplace:
<cfset num = reReplace(string, "\D*(\d+).*", "\1") />
- reFind:
<cfset match = reFind("\d+", string, 1, TRUE) />
<cfset num = mid(string, match.pos[1], match.len[1]) />
All of the above would return the same result, unless a number wasn't found in the string, in which case the reFind()
-based method would throw an error since the mid()
function would be passed a start
value of 0. I think it's pretty clear from the above which approach is easiest to use for a situation like this, and it would be easy to envision scenarios where this functionality could more drastically improve code brevity.
Still, that's just the beginning of what reMatch()
can do. Change the scope
argument from the default of "ONE" to "ALL" (to follow the convention used by reReplace()
, etc.), and the function will return an array of all matches. Finally, set the returnLenPos
argument to TRUE and the function will return either a struct or array of structs (based on the value of scope
) containing the len, pos, AND value of each match. This is very different from how the returnSubExpressions
argument of reFind()
works. When using returnSubExpressions
, you get back a struct containing arrays of the len and pos (but not value) of each backreference from the first match.
Here's the code, with four additional UDFs (reMatchNoCase()
, match()
, matchNoCase()
, and reEscape()
) added for good measure:
See the demo and get the source code.
Now that I've got a deeply featured match function, all I need Adobe to add to ColdFusion in the way to regex support is lookbehinds, atomic groups, possessive quantifiers, conditionals, balancing groups, etc., etc.…