2010-05-06 25 views
3

我正在使用ColdFusion的reReplace()函数进行正则表达式模式替换。ColdFusion - 传递正则表达式反向引用函数调用

我想使用替换字符串的函数调用,并将匹配的反向引用传递给它。

事情是这样的:

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

但失败,因为“参数值3,这是目前\ 1,必须是一个类java.util.Date中的价值。”

有没有其他办法可以达到这个目的?

感谢, 斯图

+0

关于为什么不起作用的说明:CF将正则表达式评估转交给Java引擎,该引擎需要字符串参数。因此,CF会在尝试将所有内容评估为字符串之前进行评估。我们都希望你能传递函数,但它不起作用。虽然加里有正确的想法。 – 2010-05-06 14:06:21

+0

啊哈 - 有趣的东西。我想这就是我真正想知道的 - 但我不能将评论标记为已接受的答案:-) – stubotnik 2010-05-06 15:14:03

回答

2

我不太确定你想要做什么可以通过你的例子中描述的方法,但这里是一个应该工作的另一种方法的大纲。

  1. 地带出日期字符串
  2. 转换使用CreateDateTime
  3. 这个对象上的任何日期的操作即使用DateAdd
  4. 转换回使用日期格式
  5. 做一个字符串,这刺痛的时间对象替换

当使用内置的ColdFusion日期和时间函数时,我总是确保我传递一个日期/ ti我反对那个需要日期/时间对象的参数的日期/时间字符串。这是因为ColdFusion可能会将字符串天数解释为月份,反之亦然。

+0

你可能想要parseDate()而不是createDateTime(),但其他方面的钱。 – 2010-05-06 14:04:36

+0

嗨加里 - 我希望避免因性能原因而走上这条路(见安德烈亚斯的回答评论),但看起来我没有别的选择。接受这个答案 - 欢呼 – stubotnik 2010-05-06 15:13:11

0

据我可以从你的代码示例见,你要一小时后用日期来代替比你的字符串显示整个字符串。由于reReplace存在问题,我会尝试使用replace()replaceNoCase()函数去除字符串的非日期部分。

<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()需要一个有效的日期为参数,我不认为你可以用一个正则表达式反向引用,这将是百达一串做到这一点。

+0

嗨安德烈亚斯 - 感谢您的回复。这个例子是超简化的来解释我的问题。我真正需要做的是在大型文本文档中内联替换多次出现的日期。所以只是提取日期不适合我。并重复调用returnsubexpressions = true重新调用,然后调用替换每个比赛太慢...谢谢! – stubotnik 2010-05-06 13:05:18

1

我有一个实用工具,可以让你实现你想要的。

语法不完全相同,有点刺激'简单'的东西,但最终它更灵活。

基本上你写了一个函数,它接受一个Match字符串和Groups数组,并返回一个String - 在函数内部,你可以做你喜欢的事情,并且它会被应用到每个匹配上。

像这样:

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


详情和下载在这里: http://www.hybridchill.com/projects/jre-utils.html

有一点要记住的是,这个使用java.util.regex中引擎,这与CF的org.apache.oro.text.regex引擎不同,并且虽然这提供了更多特征,但fe w事情不起作用(还)。

下一个版本将会是一个相当重要的版本,所以你可能有任何反馈都非常受欢迎。

具体来说,一个功能我一直在琢磨的是如何避免长篇大论的手动功能回调方法如上 - 也许让这样的事情:

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

将是很好的听到的话,任何人有对此的想法。

+0

嗨,彼得 - 这个例子对我来说没有找到“找到appendReplacement方法”。但除此之外,这看起来完全像我所希望的。谢谢! – stubotnik 2010-05-13 09:04:07

+0

嗨stubotnik,这有点奇怪,appendReplacement方法是Java的一部分,并且从1.4开始就已经存在(而且我没有在1.4之前运行CF) - 你能确认你正在运行的CF和Java版本吗? – 2010-05-13 09:35:57

+0

CF 9和Java 1.6.0_14。当CF在转换变量和找出正确的重载方法时遇到问题时会抛出“找不到方法”。也许这是问题? – stubotnik 2010-05-13 10:40:01

相关问题