15

正是标题所要求的。在解释我的问题时,我将提供一些示例。

测试字符串:

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

说,我想提取#(所有foos 但不是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

接受纯 JS 和 jQuery 答案,如果您使用console.log. =]

4

5 回答 5

17

你也可以.exec像下面这样使用来构建一个数组

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

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

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

工作小提琴

这里找到

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

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

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

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

当您这样做时,搜索将从正则表达式的 lastIndex 属性指定的 str 的子字符串开始(测试也将推进 lastIndex 属性)。

于 2012-06-04T04:53:28.957 回答
4

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

var matches = [];

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

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

alert(JSON.stringify(matches));

希望能帮助到你。

于 2012-06-04T04:43:02.757 回答
2

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

于 2012-06-04T05:08:20.717 回答
1

如果有人带着类似的需求到达,我需要一个 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) );
于 2014-10-01T15:29:20.537 回答
0

另一个想法,尽管 exec 一样有效。

var s= "#foo# #foo# bar #foo#";
s= s.match(/#([^#])*#/g).join('#').replace(/^#+|#+$/g, '').split(/#+/);
于 2012-06-04T05:04:28.660 回答