views:

68

answers:

4

I need to parse some CSS code like:

color: black;
font-family:"Courier New";
background:url('test.png');
color: red;
--crap;

Into:

array (
    'color'=>'red',
    'font-family'=>'"Courier New"',
    'background'=>'url(\'test.png\')',
    '--crap'=>''
)
  • I need to do this via PHP. I can see this done easily via regexp (well, easy to those that know it, unlike myself :-) ).
  • I need the resulting array to be "normalized", there should not be any trailing spaces between tokens, even if they were in the source.
  • Valueless css tokens should be included in the array as a key only. (see --crap)
  • Quotes (and values in general) should remain as is, except for extra formatting (spaces, tabs); easily removed via trim() or via the relevant regexp switch.
  • Please not that at this point, I specifically do not need a full CSS parser, ie, there is no need to parse blocks ( {...} ) or selectors ( a.myclass#myid ).
  • Oh, and considering I'll be putting this stuff in an array, it is perfectly ok if the last items ( color:red; ) completely override the original items ( color:black; ).
+1  A: 

Here's a simple version:

    $a = array();
    preg_match_all('/^\s*([^:]+)(:\s*(.+))?;\s*$/m', $css, $matches, PREG_SET_ORDER);
    foreach ($matches as $match)
            $a[$match[1]] = isset($match[3]) ? $match[3] : null;

Sample output:

array(4) {
  ["color"]=>
  string(3) "red"
  ["font-family"]=>
  string(13) ""Courier New""
  ["background"]=>
  string(15) "url('test.png')"
  ["--crap"]=>
  NULL
}

Not tested with anything except your source data, so I'm sure it has flaws. Might be enough to get you started.

konforce
That sounds just about what I need. Thanks!
Christian Sciberras
A: 

You can try:

$result = array();
if(preg_match_all('/\s*([-\w]+)\s*:?\s*(.*?)\s*;/m',$input,$m))
        var_dump($m);
        // $m[1] contains all the properties
        // $m[2] contains their respective values.
        for($i=0;$i<count($m[1]);$i++) {
                $result[$m[1][$i]] = $m[2][$i];
        }
}
codaddict
No such an assumption, sorry ;-)
Christian Sciberras
It works without the assumption now.
codaddict
A: 

I found this few weeks back and looks interesting.

http://websvn.atrc.utoronto.ca/wsvn/filedetails.php?repname=atutor&amp;path=/trunk/docs/include/classes/cssparser.php

Example:

$Parser = new cssparser();
$Results = $Parser->ParseStr("color: black;font-family:"CourierNew";background:url('test.png');color: red;--crap;");
RobertPitt
Considering I need to capture any CSS data, I really don't need this. Also considering it parses selectors (and validates them?!) this is a huge no go.
Christian Sciberras
Instead of using `ParseStr` you can use `Parse` like `Parse('path/to/style.css')`, the main reason I posted this to show you an alternative to all the regex everyone would be posting, my version tho larger is probably much faster
RobertPitt
A: 

Why don't take a look at CSSTidy?

fabrik
Again, that code specifically parses the full CSS format; while I just need to parse the format in a CSS block (or style attribute).
Christian Sciberras