了解“全球”RegExp

时间:2011-12-15 16:18:35

标签: javascript regex algorithm match combinations

我期望"test".match(/[a-z]{0,}/g);的输出应包含'', 't', 'e', 's', 't', 'te', 'es', 'st'等。

但是我只从控制台获得'''test'。这里发生了什么?

6 个答案:

答案 0 :(得分:4)

你的正则表达式匹配第一遍的全文,第二遍的空字符串,这就是原因。

不幸的是,你想要的是正则表达式引擎支持\G修饰符(IIRC),ECMA 262正则表达式没有。

答案 1 :(得分:2)

如果你要找的是所有的单词组合,这里有一个我曾经使用过的代码:

<html>
<body>

<script type="text/javascript">
function removeDuplicateElement(arrayName) {
    var newArray=new Array();
    label: for(var i=0; i<arrayName.length;i++){
        for(var j=0; j<newArray.length;j++) {
            if(newArray[j]==arrayName[i]) 
                continue label;
        }
        newArray[newArray.length] = arrayName[i];
    }
    return newArray;
}

var all=new Array();
var str="test";
for (;str.length>0;str=str.substring(1,str.length)) {
    for (var i = 0; i<=str.length;i++){
        var patt1=new RegExp("([a-z]{"+i+","+i+"})", "g");
        all=all.concat(str.match(patt1));
    }
}

document.write(removeDuplicateElement(all));
</script>

</body>
</html>

对于'test',它返回',t,e,s,te,st,tes,test,es,est'。

答案 2 :(得分:1)

您只会获得["", "test"],因为量词{0,}将匹配零或任意数量的字母(就像*)并且是贪婪的(就像*)所以它匹配它可以找到的最大数量(和零)。

答案 3 :(得分:1)

如果您想自己创建此功能,可以尝试以下方法:

String.prototype.fullMatch = function () {
    var matches = [""]; // "" is always a match

    function do_regex(str, startAt) {
        var len = str.length,
            i,
            j,
            regex,
            all_matches = [];

        for (i = startAt; i < len; i++) {
            regex = new RegExp("[a-z]{" + (i + 1) + "}", "g");
            all_matches = str.match(regex);
            for (j = 0; j < all_matches.length; j++) {
                matches.push(all_matches[j]);
            }
        }
    }

    for (var k = 0; k < this.length; k ++) {
        do_regex(this.substring(k), k);
    }

    return matches;  
};

console.log("test".fullMatch()); // ["", "t", "e", "s", "t", "te", "st", "tes", "test", "es", "est"]

答案 4 :(得分:1)

将字符串与全局正则表达式匹配将始终为您提供尽可能长的非重叠子字符串。第一个最长匹配是整个字符串"test",然后空字符串""仍然存在,这也是匹配。你可以通过匹配几个具有不同长度说明符的正则表达式来达到你想要的效果,如下所示:

"test".match(/[a-z]{0}/g);
"test".match(/[a-z]{1}/g);
"test".match(/[a-z]{2}/g);
"test".match(/[a-z]{3}/g);
"test".match(/[a-z]{4}/g);

当然,这应该更优雅;例如,您可以使用new RegExp("[string]")动态构造这些正则表达式。不过,例如,这不会产生"es"(尽管你可以再次解决这个问题),但根据你的问题,你不想得到这个匹配。

答案 5 :(得分:1)

match返回一个匹配数组,每个匹配项在上一个匹配结束后开始。如果您改为使用"test".match(/[a-z]/g);,则会得到["t", "e", "s", "t"]。 “t”匹配,“t”之后匹配的下一个东西是“e”...

在你的查询中,正则表达式匹配整个字符串,因此它会发出“test”,之后“test”后面的空字符串匹配(因为你使用了{0,}而不是{1,}。