exec没有返回arr [1] - n中的匹配项

时间:2015-04-13 21:32:15

标签: javascript regex exec

我有一个正则表达式,我试图从getComputedStyle对象中获取一些值。我希望当我在每次迭代时从exec运行它,从索引1开始,我的匹配将被定位,但是在每次迭代时,两个新元素被添加到myArray,之前设置的元素现在是未定义的。

var styleAsDashedStr = window.getComputedStyle(document.getElementById("container")).cssText;
var styleRe = /(?:;\s?(background.*?)\:\s?(.*?);)|(?:;\s?(font.*?)\:\s?(.*?);)|(?:;\s?(border.*?)\:\s?(.*?);)|(?:;\s?(margin.*?)\:\s?(.*?);)|(?:;\s?(padding.*?)\:\s?(.*?);)/g;
//var individuallySetStyles = styleAsDashedStr.match(styleRe);

var myArray;
while ((myArray = styleRe.exec(styleAsDashedStr)) !== null) {
    console.log(myArray);
}

第一次迭代

0: "; background-blend-mode: normal;"
1: "background-blend-mode"
2: "normal"
3: undefined
4: undefined
5: undefined
6: undefined
7: undefined
8: undefined
9: undefined
10: undefined

后续迭代定义了两个元素,但其他8个元素没有定义。有没有办法得到一个数组,其中元素一和二是当前的捕获?

2 个答案:

答案 0 :(得分:2)

对所有样式名称使用​​单个捕获组,而不是单独的组。

var styleRe = /\b((?:background|font|border|margin|padding).*?)\:\s?([^;]*?)/g;

请注意,您不应该在开头和结尾匹配;,因为这会导致它跳过第一个样式(因为它之前没有;)然后是其他每个样式(因为匹配一端的;将阻止匹配下一个开头的;。我在最后使用[^;]*代替.*?完全避免了这种情况。

答案 1 :(得分:1)

您可以累积一个对象来保存您找到的规则:

var myArray, rules = {};
while ((myArray = styleRe.exec(styleAsDashedStr)) !== null) {
    console.log(myArray);
    if (myArray[1] && myArray[2])
      rules[myArray[1]] = myArray[2];
}

这样你最终会得到一个包含所有匹配属性的对象。

你也可以简化你的正则表达式(就像Barmar在编辑时给出的答案一样)。

编辑 - 您的模式存在的问题是您的" stanzas"使用;开始和结束。当你匹配某些东西时,匹配将包括起始分号和它后面的分号。 匹配的分号后,下一个匹配将开始,因此需要带分号的模式部分将失败。