使用REFind在String中查找多个出现次数

时间:2013-09-10 19:39:38

标签: coldfusion coldfusion-10

我正在尝试让ColdFusion的REFindNoCase函数返回匹配字符串的多个实例,但似乎无法使其工作:

<cfset string2test="cfid skldfjskdl cfid sdlkfjslfjs cftoken dslkfjdslfjks cftoken">
<cfset CookieCheck =  REFindNoCase( 'CFTOKEN', string2test, 1, true)>
<cfif arrayLen( CookieCheck['LEN'] ) gt 1>
    MULTIPLE CFTOKEN!
</cfif>

我需要使用正则表达式魔术语法来搜索多于1个?

3 个答案:

答案 0 :(得分:2)

上面代码的语法将创建带有数组(LEN,POS)的结构,用于模式匹配和子表达式。 RegEx子表达式在模式中的括号内。 'CFTOKEN'模式不包含子表达式。

我认为REFindNoCase不会做你想要完成的事情。

例如,如果您使用'。*?(cftoken)'作为模式:

<cfset CookieCheck =  REFindNoCase('.*?(CFTOKEN)', string2test, 1, true)>

(CFTOKEN)是一个子表达式。如果删除“?”,则返回最后一次'cftoken'的信息。

第一个数组项中的值将匹配整个模式,直到第一个'cftoken'(字符串的前40个字符)。第二组值将标识在第一场比赛中找到的'cftoken'字符串(前40个字符)。

因为示例中的语句不包含子表达式,所以只返回第一个模式匹配。

如果您需要检查是否多次列出某些内容,或者您​​不需要操作原始字符串,我建议您使用REMatchNoCase()。它返回一组模式匹配但没有位置信息。

答案 1 :(得分:1)

您可以创建一个自定义方法来循环遍历字符串,并将每个匹配项放入一个数组(或结构,或任何您想要的)。以下是我如何处理它的一个例子:

<cfscript>
public array function reFindMatches(required string regex, required string str) {
    var start = 1;
    var result = [];
    var matches = [];
    var match = '';
    do {
        matches = ReFind(arguments.regex, arguments.str, start, true);
        if ( matches.pos[1] ) {
            match = matches.len[1] ? Mid(arguments.str, matches.pos[1], matches.len[1]) : '';
            ArrayAppend(result, match);
            start = matches.pos[1] + matches.len[1];
        }
    } while(matches.pos[1]);
        return result;
}

testString = 'cfid skldfjskdl cfid sdlkfjslfjs cftoken dslkfjdslfjks cftoken';
regex = '(?i)(\bcftoken\b)';
check = reFindMatches(regex=regex, str=testString);

WriteDump(var=check);
</cfscript>

我包含的示例正则表达式以(?i)开头,表示搜索不区分大小写。所以,没有必要调用ReFindNoCase ...你可以直接传入你想要使用的正则表达式。

上面的代码应该输出一个包含两个元素的数组,其中包含单词 cftoken

答案 2 :(得分:0)

如果您需要来计算有多少个实例,请使用rematch(或rematchNoCase)。


如果你需要的只是来确定是否有多个,你可以这样做:

<cfset FirstInstance = refindNoCase( 'cftoken' , string2test ) />

<cfif FirstInstance AND refindNoCase( 'cftoken' , string2test , FirstInstance+7 ) >
    ... more than one instance ...
</cfif>

这可能比使用子表达式或循环多次重新匹配更有效。


根据相关数据,可能更有效地执行以下操作:

<bfif string2text.indexOf('cftoken') NEQ string2text.lastIndexOf('cftoken') >

(即,如果您知道其他实例总是在字符串末尾附近,而最初的实例则不是。)