1

This must be simple somehow but I can't figure it out and have been at it for the whole day already.

I want to parse a CSS file into an array with keys and values like this:

Array('#idname' => Array('overflow' => hidden, 'color' => '#FFF'));

I ignore all media queries by removing them with a regular expression and also remove all whitespace.

//Remove all media queries
$cssFromLink = preg_replace("/@media.*?}}/i", '', $cssFromLink);
//Remove all whitespace
$cssFromLink = str_replace(' ','', $cssFromLink);

All that I want is to be able to search in a list for an id or classname and then extract a property like background-color.

Libraries like Sabberworm and other CSS parsers don't seem to work for me, they either seem to be taking forever/do nothing or throw a fatal error. I am trying this on the css from apple.com.

All others solutions look equally complex to me but almost none of them seem to work for apple.com specifically and I can't have it crash on popular websites.

Aseliot
  • 87
  • 1
  • 11
  • 1
    Possible duplicate of [Parse a CSS file with PHP](http://stackoverflow.com/questions/3618381/parse-a-css-file-with-php) – samlev Nov 05 '15 at 15:44

2 Answers2

1

The answer from JapanPro at Parse a CSS file with PHP works the best for me. It still has some errors (a } is in front of some id's) and i'm not sure if using regex is the best way to parse it for every situation but for now I will use this.

<?php

$css = <<<CSS
#selector { display:block; width:100px; }
#selector a { float:left; text-decoration:none }
CSS;

//
function BreakCSS($css)
{

    $results = array();

    preg_match_all('/(.+?)\s?\{\s?(.+?)\s?\}/', $css, $matches);
    foreach($matches[0] AS $i=>$original)
        foreach(explode(';', $matches[2][$i]) AS $attr)
                if (strlen($attr) > 0) // for missing semicolon on last element, which is legal
                {
                        // Explode on the CSS attributes defined
                        list($name, $value) = explode(':', $attr);
                        $results[$matches[1][$i]][trim($name)] = trim($value);
                }
    return $results;
}
var_dump(BreakCSS($css));
Community
  • 1
  • 1
Aseliot
  • 87
  • 1
  • 11
  • [link only answers are not good](http://meta.stackexchange.com/questions/8231/are-answers-that-just-contain-links-elsewhere-really-good-answers). Please add some code that relates to the link you posted. – Novocaine Nov 06 '15 at 09:59
0

I just made this, try it out:

<?php

    //To test
    $string = "#id {
        overflow: hidden;
        color: #fff;
    }
    #id2 {
        margin: 0px;
        height: 100%;
    }";

    //Call the function and print it out
    $css_array = cssToArray($string);
    echo "<pre>";
    print_r($css_array);

    //The actual function
    function cssToArray($css){
        //Regex to find tags and their rules
        $re = "/(.+)\{([^\}]*)\}/";
        preg_match_all($re, $css, $matches);

        //Create an array to hold the returned values
        $return = array();
        for($i = 0; $i<count($matches[0]); $i++){
            //Get the ID/class
            $name = trim($matches[1][$i]);

            //Get the rules
            $rules = trim($matches[2][$i]);

            //Format rules into array
            $rules_a = array();
            $rules_x = explode(";", $rules);
            foreach($rules_x as $r){
                if(trim($r)!=""){
                    $s = explode(":", $r);
                    $rules_a[trim($s[0])] = trim($s[1]);
                }
            }

            //Add the name and its values to the array
            $return[$name] = $rules_a;
        }

        //Return the array
        return $return;
    }
Ben
  • 8,894
  • 7
  • 44
  • 80
  • At least that did something. But it came out as this http://s14.postimg.org/uabenw735/resultcss.png – Aseliot Nov 05 '15 at 15:34
  • That's because your last rule on each set doesn't have the final `;` – Ben Nov 05 '15 at 15:35
  • If that's the case for *all* your CSS rules, do a find/replace, replacing "}" with ";}" and it should work – Ben Nov 05 '15 at 15:36
  • It's a valid syntax right? But i replaced all } with ;} to test it and it still gives the same output. My own idea was to just loop through the string and then match everything within the {} quotes with an id/class as it doesn't really matter to me what the rule is. – Aseliot Nov 05 '15 at 15:49
  • Could you post your CSS code into a [PasteBin](http://pastebin.com/) and post it here? – Ben Nov 05 '15 at 15:56
  • Sure. but it is supposed to be variable, right now I am using cURL to get all CSS from apple.com and append all of it into one string so it's quite huge. http://pastebin.com/h8Ykjkp7 – Aseliot Nov 05 '15 at 16:03