Question

I'm using ColdFusion's reReplace() function for regular expression pattern replacement.

I'd like to use a function call for the replacement string, and pass a matched backreference to it.

Something like this:

<cfset s = "STARTDATE_2010-05-07 00:05:00.0_ENDDATE" />
<cfset s = reReplace(s, "STARTDATE_([\s-.:0-9]*)_ENDDATE", dateAdd("h", 1, "\1")) />

But that fails because "The value of parameter 3, which is currently \1, must be a class java.util.Date value."

Is there any other way to achieve this?

Thanks, Stu

Was it helpful?

Solution

I'm not too sure if what you're wanting to do is possible by the approach described in your example, but here is an outline of another approach that should work.

  1. Strip out the date string
  2. Convert this sting to a time object using CreateDateTime
  3. Perform any date operations on this object ie DateAdd
  4. Convert back to a string using DateFormat
  5. Do the replace

When using the built-in ColdFusion date and time functions I like to always make sure I'm passing in a date/time object rather that a date/time string for parameters that require a date/time object. This is because ColdFusion may interpret the strings days as months or vice versa.

OTHER TIPS

I have a utility that allows you to achieve what you want.

Syntax isn't quite a same, and a tad irritating for 'simple' things, but ultimately it is more flexible.

Basically you write a function which accepts a Match string and Groups array and returns a String - inside the function you can do what you like and it'll get applied to each match.

Like so:

<cfset Jrex = createObject('component','jre-utils').init() />


<cfset MyString = "STARTDATE_2010-05-07 00:05:00.0_ENDDATE" />
<cfset MyRegex = "STARTDATE_([\s-.:0-9]*)_ENDDATE" />
<cfset MyString = Jrex.replace( MyString , MyRegex , addHour , 'all' )/>


<cffunction name="addHour" returntype="String" output="false">
    <cfargument name="Match"  type="String"/>
    <cfargument name="Groups" type="Array" default="#ArrayNew(1)#"/>

    <cfset var Result = DateAdd('h',1,Groups[1]) />

    <cfreturn DateFormat( Result , 'yyyy-mm-dd' )
        & ' ' & TimeFormat( Result , 'HH:mm:ss' )
        />
</cffunction>


Details and download here: http://www.hybridchill.com/projects/jre-utils.html

One thing to bear in mind is that this uses the java.util.regex engine, which is different to CF's org.apache.oro.text.regex engine, and whilst this provides more features, a few things don't work (yet).

The next version is going to be a fairly major release, so any feedback you might have is very much welcome.

Specifically, one functionality I've been pondering is how to avoid the long-winded manual function callback method as above - perhaps enabling something like this:

Jrex.replace( MyString , MyRegex , "\F:DateAdd('h',1,\1)" , 'all' )

Would be good to hear if anyone has thoughts on that.

As far as I can see from your code example, you want to replace the whole string with a date one hour later than shown in your string. Since there are troubles with the reReplace I would try to strip off the non-date part of the string using the replace() or replaceNoCase() functions.

<cfset s = "STARTDATE_2010-05-07 00:05:00.0_ENDDATE" />
<cfset s = replaceNoCase(replaceNoCase(s, "STARTDATE_", ""),"_ENDDATE","")>
<cfoutput>
    <cfif isDate(s)>
        before: #s# after: #dateAdd("h", 1, s)#
    </cfif> 
</cfoutput>

dateAdd() requires a valid date as parameter, I don't think you can do this with a regex backreference which will allways be a string.

Licensed under: CC-BY-SA with attribution
Not affiliated with StackOverflow
scroll top