3

我试图让 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 个吗?

4

3 回答 3

2

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

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

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

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

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

第一个数组项中的值将匹配整个模式,直到第一个“cftoken”(字符串的前 40 个字符)。第二组值将识别在第一个匹配项(前 40 个字符)中找到的“cftoken”字符串。

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

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

于 2013-09-12T00:05:38.183 回答
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

于 2013-09-10T20:10:05.060 回答
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') >

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

于 2013-09-12T00:21:10.900 回答