Reputation: 15369
I have a regex that I'm using to try to get some values from the getComputedStyle
object. I would expect that when I run it against exec
at each iteration starting at index 1 my matches would be located, but at each iteration two new elements are added to myArray
and elements set before are now undefined.
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);
}
First iteraction
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
And subsequent iterations have two elements defined, but the other 8 are not. Is there a way to get an array where elements one and two are the current captures?
Upvotes: 0
Views: 33
Reputation: 413916
You could accumulate an object to hold the rules you find:
var myArray, rules = {};
while ((myArray = styleRe.exec(styleAsDashedStr)) !== null) {
console.log(myArray);
if (myArray[1] && myArray[2])
rules[myArray[1]] = myArray[2];
}
That way you'd end up with an object that contained all the matched properties.
You could simplify your regex too (as in the answer Barmar just gave while I was editing :).
edit — a problem with your pattern is that your "stanzas" both begin and end with a ;
. When you match something, the match will involve both the starting semicolon and the one that comes after it. The next match will start after the matched semicolon, so the parts of the patterns that require a leading semicolon will fail.
Upvotes: 1
Reputation: 782130
Use a single capture group for all the style names, not separate groups.
var styleRe = /\b((?:background|font|border|margin|padding).*?)\:\s?([^;]*?)/g;
Note that you shouldn't match ;
at the beginning and end, because this will cause it to skip the first style (since there's no ;
before it) and then every other style (because matching the ;
at the end of one will prevent matching the ;
at the beginning of the next one). I've avoided this completely by using [^;]*
instead of .*?
at the end.
Upvotes: 2