views:

41

answers:

2

I need to use JavaScript split but I'm useless at regex so what i wanna do is take a text which is CSS like structure eg:

var str = "selector {
  width: 100px;
  height: 20px;
}

.anything{
  margin: 5%;
}"; 

str.split(/regex goes here/);

Expected output

[
  0 = selector{width: 100px; height: 20px;},
  1 = .anything{margin: 5%;}
]

Hopefully it's not too confusing but please ask if in doubt.

Thanks.

+5  A: 

I wouldn't use a split for this. Instead, use this regex to extract each rule:

([\s\S]*?{[\s\S]+?})

Very simple, but should work as long as there aren't { and } characters in the rules themselves (which I would expect would be rare). My regex ignores whitespace and newlines as long as the CSS is syntactically valid. I used [\s\S] in place of . because . doesn't match newlines.

In your case, to extract the rules it would be:

var myCSS = "CSS goes here";
var rules = myCSS.match(/([\s\S]*?{[\s\S]+?})/);

EDIT:

As per the askers request, I have modified my regex to ignore a selector such as: a {}. However, it will still catch a { }. I will try to find a solution for this but in the mean time you might just have to process each rule and remove empty ones.

SimpleCoder
thnx that does the job... so what if i decide to put a {} inside the rule would there be a way to ignore them ?
Val
Ah, change the second `*` to a `+`. (See modified answer).
SimpleCoder
omg thnx I have been playing about with regex i still don't understand it to do the things I want it to do :) ... you have svaed me a life time because thats how long it would have taken me :)... im doing this script and i'd like to put ur credits in it, if you like post your details that want to go on the credits. thnx again
Val
You are welcome! Thanks for the offer, but you don't need to accredit me :). Also, make sure you check each extracted rule that it's not empty. Try using: `myRule.test(/[\s\S]*{\s*}/);`. If that expression evaluates to true, the rule is empty.
SimpleCoder
+1  A: 

Regexps are not for parsing. You should write or find a CSS parser to do the job, but then that could make your code longer.

Try this:

var style = document.createElement('style');
style.innerHTML = ".test { color: red; } .test2 { }";
var head = document.getElementsByTagName('head')[0];
head.appendChild(style);
var style = document.styleSheets[document.styleSheets.length - 1];
style.disabled = true;
var rules = style.cssRules;
var list = [];
for (var i = 0; i < rules.length; i ++) {
  list.push(rules[i].cssText + "");
}
list;

It asks the browser's CSS parser to do the job for you.

Due to the non-recursive nature of the CSS syntax, you can write a giant regexp to parse CSS.

SHiNKiROU
nice one thanx :) they will now dissmiss extra "{}" withing the rule so for example `select { value : {value} }` which is what i need to do.
Val