Перерыв CSS-файла в массив с PHP
Я хотел разбить файл css в массив с PHP.
Пример:
#selector{ display:block; width:100px; } #selector a{ float:left; text-decoration:none; }
В php-массив …
array(2) { ["#selector"] => array(2) { [0] => array(1) { ["display"] => string(5) "block" } [1] => array(1) { ["width"] => string(5) "100px" } } ["#selector a"] => array(2) { [0] => array(1) { ["float"] => string(4) "left" } [1] => array(1) { ["text-decoration"] => string(4) "none" } } }
Есть идеи?
О: Изменить: я не беспокоюсь о плохо сформированных CSS-файлах в этом случае. Не должно быть пуленепробиваемым, пока его не жадность
4 Solutions collect form web for “Перерыв CSS-файла в массив с PHP”
Это должно сделать это:
<?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(trim($attr)) > 0) // for missing semicolon on last element, which is legal { list($name, $value) = explode(':', $attr); $results[$matches[1][$i]][trim($name)] = trim($value); } return $results; } var_dump(BreakCSS($css));
Краткое пояснение: Регулярное выражение простое и скучное. Он просто соответствует всем «всем, возможному пространству, фигурной скобке, возможному пространству, чему угодно, закрывает фигурные скобки». Оттуда первое совпадение является селектором, второе совпадение – списком атрибутов. Разделите это точкой с запятой, и вы останетесь с парами ключ / значение. Некоторые trim () там, чтобы избавиться от пробелов, и это все.
Я предполагаю, что ваша следующая лучшая ставка, вероятно, заключалась бы в том, чтобы взорвать селектор запятой, чтобы вы могли консолидировать атрибуты, относящиеся к одной и той же вещи и т. Д., Но я сохраню это для вас. 🙂
Edit: Как уже упоминалось выше, реальный грамматический анализатор был бы более практичным … но если вы принимаете хорошо сформированный CSS, нет причин, по которым вам нужно делать что-либо сверх простейшего из «ничего {ничего}». На самом деле зависит от того, что вы хотите с этим делать.
Если вам нужно то же самое для правил CSS с несколькими селекторами и с разделительными линиями:
<?php $css = " #selector { display:block; width:100px; } #selector a:hover div.asd, #asd h1.asd { float:left; text-decoration:none; } "; preg_match_all( '/(?ims)([a-z0-9\s\,\.\:#_\-@]+)\{([^\}]*)\}/', $css, $arr); $result = array(); foreach ($arr[0] as $i => $x) { $selector = trim($arr[1][$i]); $rules = explode(';', trim($arr[2][$i])); $result[$selector] = array(); foreach ($rules as $strRule) { if (!empty($strRule)) { $rule = explode(":", $strRule); $result[$selector][][trim($rule[0])] = trim($rule[1]); } } } var_dump($result); ?>
вывод:
array(2) { ["#selector"]=> array(2) { [0]=> array(1) { ["display"]=> string(5) "block" } [1]=> array(1) { ["width"]=> string(5) "100px" } } ["#selector a:hover div.asd, #asd h1.asd"]=> array(2) { [0]=> array(1) { ["float"]=> string(4) "left" } [1]=> array(1) { ["text-decoration"]=> string(4) "none" } } }
Обновление: добавлена поддержка нескольких селекторов, таких как: .box, .element, div {…}
Если бы я был вами, я бы построил (или нашел) настоящую грамматику для CSS и разбирался таким образом. Попытка написать парсер для любого нетривиального языка выражений (а CSS явно не тривиальна, со всеми фантастическими селекторами) заставила меня беспокоиться более чем достаточно раз.
Пример: http://www.phpclasses.org/package/1289-PHP-CSS-parser-class.html
Я бы предложил селектор (?ims)([a-z0-9\s\,\.\:#_\-@*()\[\]"=]+)\{([^\}]*)\}
в ответе inakiabt для лучшего решения.