我对ColdFusion的正则表达式有点问题。
我有一个字符串:
Hi my name is {firstname}. and i live in {towncity} my email address is {email}
我想知道的是,如何在我的字符串中查找包含在{}
括号内的所有字符串?我想将所有匹配的字符串拆分成一个数组,以便我可以使用查询数据的结果。
这也是在匹配字符串中处理字符串以合并变量数据的常用模式吗?
非常感谢任何帮助。
答案 0 :(得分:5)
要查找所有括号括起的字符串,您可以使用rematch和简单表达式\{[^{}]+\}
每个大括号前的反斜杠\
都要逃避它们,并让它们作为文字大括号(否则它们带有特殊含义)。
[^
... ]
是一个负字符类,表示匹配任何不包含在其中的单个字符,并且贪婪的+
量词表示它匹配来自前一项目的尽可能多,但至少有一项。
因此在大括号之间使用[^{}]+
意味着它不匹配嵌套或不匹配的大括号。 (虽然使用\{.*?\}
可以匹配两个开口括号。注意:*?
是一个惰性量词,它不匹配任何东西(如果可能),但是根据需要匹配。)
但是,由于您说结果来自查询,因此只能匹配您正在处理的值的方法是使用查询的ColumnList来形成表达式:
`\{(#ListChangeDelims(QueryName.ColumnList,'|')#)\}`
这将ColumnList更改为以管道分隔的列表 - 一组备选项,按括号分组 - 即生成的模式将如下所示:
\{(first_name|towncity|email)\}
(该组的内容进入捕获组1)。
要实际填充文本(而不仅仅是匹配),你可以做类似的事情,除了这里不需要正则表达式,只是在循环列中时直接replace:
<cfloop index="CurColumn" list=#QueryName.ColumnList#>
<cfset text = replace( text , '{#CurColumn#}' , QueryName[CurColumn][CurrentRow] , 'all' ) />
</cfloop>
(因为这是标准替换,所以不需要使用反斜杠来逃避括号;它们在这里没有特殊含义。)
答案 1 :(得分:1)
使用reMatch(reg_expression, string_to_search)
功能。
Coldfusion 10中正则表达式的详细信息为here。 (我相信CF8中的正则表达式大致相同。)
使用以下代码。
<cfset str = "Hi my name is {firstname}. And I live in {towncity} my email address is {email}.">
<cfoutput>Search string: <b>#str#</b><br />Search result:<br /></cfoutput>
<cfset ret = reMatch("\{[\w\s\(\)\+\.@-]+\}", str)>
<cfdump var ="#ret#">
这将返回一个包含以下条目的数组。
CF正则表达式中的[]
括号定义了一个匹配单个字符的字符集。您将+
放在括号后面,以匹配[]
中定义的字符集中的一个或多个字符。例如,要匹配一个或多个大写字母,您可以编写[A-Z]+
。
如上面的链接所详述,CF定义了匹配各种字符的快捷方式。我在代码中使用的是:\w
以匹配字母数字字符或下划线,\s
以匹配空白字符(包括空格,制表符,换行符等)。
要匹配以下特殊字符+*?.[^$({|\
,您可以在它们前面写反斜杠\
来逃避它们。
此例外是破折号-
字符,无法使用反斜杠进行转义。因此,将它用作文字只需将其放在字符集的最末端,就像我上面所做的那样。
使用上面的正则表达式,您可以从以下字符串中提取字符,例如。
<cfset str = "Hi my name is { John Galt}. And I live in {St. Peters-burg } my email address is {john@exam_ple.com}.">
结果将是一个包含以下条目的数组。
答案 2 :(得分:0)
可能有更好的方法可以做到这一点,但使用像rematch( '{.*?}', yourstring )
之类的东西会给你一个包含所有匹配项的数组。
为了将来的参考,我用优秀的RegExr做了这个,这是一个非常好的在线正则表达式检查器。完全披露,对于ColdFusion来说,它不是特别,但它是测试事物的好方法。