Alex Rivera | Logout

Parsing CSS by regex

Asked 2008-10-25T20:32:48.467
13

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 work for all properties. I'm using preg/perl syntax in PHP.

Regex

(?<selector>[A-Za-z]+[\s]*)[\s]*{[\s]*((?<properties>[A-Za-z0-9-_]+)[\s]*:[\s]*(?<values>[A-Za-z0-9#, ]+);[\s]*)*[\s]*}

Test case

body { background: #f00; font: 12px Arial; }

Expected Outcome

Array(
    [0] => Array(
            [0] => body { background: #f00; font: 12px Arial; }
            [selector] => Array(
                [0] => body
            )
            [1] => Array(
                [0] => body
            )
            [2] => font: 12px Arial; 
            [properties] => Array(
                [0] => font
            )
            [3] => Array(
                [0] => font
            )
            [values] => Array(
                [0] => 12px Arial
                [1] => background: #f00
            )
            [4] => Array(
                [0] => 12px Arial
                [1] => background: #f00
            )
        )
)

Real Outcome

Array(
    [0] => Array
        (
            [0] => body { background: #f00; font: 12px Arial; }
            [selector] => body 
            [1] => body 
            [2] => font: 12px Arial; 
            [properties] => font
            [3] => font
            [values] => 12px Arial
            [4] => 12px Arial
        )
    )

Thanks in advance for any help - this has been confusing me all afternoon!

Edit
Report

1 Answer

8

I would recommend against using regex's to parse CSS - especially in single regex!

If you insist on doing the parsing in regex's, split it up into sensible sections - use one regex to split all the body{..} blocks, then another to parse the color:rgb(1,2,3); attributes.

If you are actually trying to write something "useful" (not trying to learn regular expressions), look for a prewritten CSS parser.

I found this cssparser.php which seems to work very well:

$cssp = new cssparser;
$cssp -> ParseStr("body { background: #f00;font: 12px Arial; }");
print_r($cssp->css);

..which outputs the following:

Array
(
    [body] => Array
        (
            [background] => #f00
            [font] => 12px arial
        )
)

The parser is pretty simple, so should be easy to work out what it's doing. Oh, I had to remove the lines that read if($this->html) {$this->Add("VAR", "");} (it seems to be a debugging thing that was left in)

I've mirrored the script here, with the above changes in

answered 2008-10-26T02:06:30.587

Your Answer