I\'m creating a CSS editor and am trying to create a regular expression that can get data from a CSS document. This regex works if I have one property but I can\'t get it to
Do not use your own regex for parsing CSS. Why reinvent the wheel while there is code waiting for you, ready to use and (hopefully) bug-free?
There are two generally available classes that can parse CSS for you:
HTML_CSS PEAR package at pear.php.net
and
CSS Parser class at PHPCLasses:
http://www.phpclasses.org/browse/package/1289.html
Building off of the current answer by Tanktalus there's a couple of improvements and edge cases to note.
\s*([^{]+)\s*\{\s*([^}]*?)\s*}
This Regex will do some space trimming and hits on some additional edge cases as listed in this example: https://regex101.com/r/qQRIHx/5
I too started to try work on delimiting the key:value pairs but quickly saw in the case where there were multiple styles per selector that things started to get trickier than I wanted. You can view version 1 of the regex where I tried to delimit the key:values and how it failed with multiple declarations here: https://regex101.com/r/qQRIHx/1
As others mentioned, you should break this up into multiple steps to parse and tokenize your css. This regex will help you obtain the declarations, but you will need to then parse those out.
You could use something like this to parse the declarations after you get your first set of matches.
([^:\s]+)*\s*:\s*([^;]+);
Example: https://regex101.com/r/py9OKO/1/
Edge CaseThe above example works great with multiple declarations, but it's possible that it's just 1 declaration with no semi-colon to end which will render in [most] browsers but break this regex.
You may also need to account for nested rules in the case that there's a media query. In this case I would try to run the css matching regex against the declarations that are extracted. If you get matches you could run recursion on it (although I'm not sure there's cases where you would have more than 1 level nested for vanilla CSS).
Edge CasesI've decided to instead use an npm package like css
or cssom
. I know this is in PHP but it's going to do a lot of heavy lifting for me and handle edge cases I keep running into.
Edit:
I ended up using Jotform's public css.js library. It has a really small footprint which was one of the main requirements I had when choosing libraries to parse CSS.