在阵列中存储JS Regex捕获组的最佳方法?

时间:2012-06-04 04:31:08

标签: javascript regex

究竟是什么标题要求。在解释我的问题时,我会提供一些例子。

测试字符串:

var test = "#foo# #foo# bar #foo#";

说,我想在#(所有foo s而不是bar)之间提取所有文字。

var matches = test.match(/#(.*?)#/g);

如上所述使用.match,它会存储所有匹配项,但它只会丢弃它看起来的捕获组。

var matches2 = /#(.*?)#/g.exec(test);

.exec方法显然只返回数组位置0中第一个结果的匹配字符串,以及我在位置1中唯一的匹配捕获组。

我已经筋疲力尽,谷歌和MDN正在寻找无济于事的答案。

所以,我的问题是,有没有更好的方法来存储匹配的捕获组而不是使用.exec循环并调用array.push来存储捕获的组?

我上面测试的预期数组应该是:

 [0] => (string) foo
 [1] => (string) foo
 [2] => (string) foo

如果您使用console.log发布JSFiddle,则接受纯JS和jQuery答案,额外的Cookie。 =]

5 个答案:

答案 0 :(得分:15)

您也可以使用.exec来构建数组

var arr = [],
    s = "#foo# #bar# #test#",
    re = /#(.*?)#/g,
    item;

while (item = re.exec(s))
    arr.push(item[1]);

alert(arr.join(' '));​

Working Fiddle

Here

找到

好吧,它仍然有一个循环,如果你不想循环,那么我认为你必须使用.replace()。在这种情况下,代码将类似于

var arr = [];
var str = "#foo# #bar# #test#"
str.replace(/#(.*?)#/g, function(s, match) {
                           arr.push(match);
                        });

检查MDN DOC中的这些行,这些行解释了我对exec如何更新lastIndex属性的查询,

  

如果正则表达式使用“g”标志,则可以使用exec   方法多次在同一个字符串中查找连续匹配。

     

执行此操作时,搜索从指定的str的子字符串开始   正则表达式的lastIndex属性(测试也将提前   lastIndex属性)。

答案 1 :(得分:4)

我不确定这是否是您正在寻找的答案,但您可以尝试以下代码:

var matches = [];

var test = "#foo# #foo# bar #foo#";

test.replace(/#(.*?)#/g, function (string, match) {
    matches.push(match);
});

alert(JSON.stringify(matches));

希望它有所帮助。

答案 2 :(得分:2)

data.replace(/.*?#(.*?#)/g, '$1').split(/#/)
没有循环,没有功能。

答案 3 :(得分:0)

另一个想法,尽管exec效率很高。

var s= "#foo# #foo# bar #foo#";
s= s.match(/#([^#])*#/g).join('#').replace(/^#+|#+$/g, '').split(/#+/);

答案 4 :(得分:0)

如果有人有类似的需求,我需要一个Django风格的URL配置处理程序的匹配函数,它可以将路径“参数”传递给控制器​​。我想出了这个。当然,如果匹配'$',它将不会很好地工作,但它不会打破'$ 1.00'。它比必要的更明确。您可以从else语句返回matchedGroups而不用for循环测试但是;;;在一个循环声明的中间有时会让人们感到害怕。

var url = 'http://www.somesite.com/calendar/2014/june/6/';
var calendarMatch = /^http\:\/\/[^\/]*\/calendar\/(\d*)\/(\w*)\/(\d{1,2})\/$/;

function getMatches(str, matcher){
    var matchedGroups = [];
    for(var i=1,groupFail=false;groupFail===false;i++){
        var group = str.replace(matcher,'$'+i);

        groupFailTester = new RegExp('^\\$'+i+'$');

        if(!groupFailTester.test(group) ){
            matchedGroups.push(group);
        }
        else {
            groupFail = true;
        }
    }
    return matchedGroups;
}

console.log( getMatches(url, calendarMatch) );