Разобрать файл CSS с помощью PHP - PullRequest
4 голосов
/ 01 сентября 2010

Я хочу проанализировать (особым образом) файл CSS с помощью PHP.

Пример:

cssfile.css:

#stuff {
    background-color: red;
}

#content.postclass-subcontent {
    background-color: red;
}

#content2.postclass-subcontent2 {
    background-color: red;
}

И я хочу, чтобы PHP возвращал мне каждое имя класса, в названии которого находится посткласс.

Результат выглядит как массив, имеющий в этом примере:

arrayentry1:
#content.postclass-subcontent
arrayentry2:
#content2.postclass-subcontent2

Но я хуже в регулярных выражениях. каким-то образом найдите «postclass», а затем возьмите линию дырки и поместите в массив.


спасибо, и я использовал его, чтобы проанализировать сим-файл css в файл confic.

$(function () {
    $.get('main.css', function (data) {
        data = data.match(/(#[a-z0-9]*?\ .?postclass.*?)\s?\{/g);
        if (data) {
            $.each(data, function (index, value) {
                value = value.substring(0, value.length - 2);
                $(value.split(' .')[0]).wrapInner('<div class="' + value.split('.')[1] + '" />');
            });
        }
    });
});

был мой окончательный код. так что я могу легко обернуть div вокруг некоторого hardcode-html без редактирования макета. так что мне просто нужно отредактировать мой cssfile и добавить туда что-то вроде

id .postclass-class {некоторые стили}

и мой код ищет идентификатор и оборачивает внутреннее содержимое div. Мне нужно это для быстрых исправлений, когда мне просто нужно добавить div вокруг чего-нибудь для очистки или фона.

Ответы [ 6 ]

15 голосов
/ 01 сентября 2010

Существует очень хороший класс синтаксического анализатора в PHP. Используй это. Вот пример кода:

<?php
include("cssparser.php");

$css = new cssparser();
$css->ParseStr("b {font-weight: bold; color: #777777;} b.test{text-decoration: underline;}");
echo $css->Get("b","color");     // returns #777777
echo $css->Get("b.test","color");// returns #777777
echo $css->Get(".test","color"); // returns an empty string
?> 
13 голосов
/ 06 июля 2011

Я нашел решение:

function parse($file){
    $css = file_get_contents($file);
    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]));
        $rules_arr = array();
        foreach ($rules as $strRule){
            if (!empty($strRule)){
                $rule = explode(":", $strRule);
                $rules_arr[trim($rule[0])] = trim($rule[1]);
            }
        }

        $selectors = explode(',', trim($selector));
        foreach ($selectors as $strSel){
            $result[$strSel] = $rules_arr;
        }
    }
    return $result;
}
$css = parse('css/'.$user['blog'].'.php');

использование:

$css['#selector']['color'];
10 голосов
/ 11 октября 2013

Для полноты картины есть еще одна библиотека для разбора CSS: sabberworm / PHP-CSS-Parser .

Домашняя страница: http://www.sabberworm.com/blog/2010/6/10/php-css-parser
GitHub: http://github.com/sabberworm/PHP-CSS-Parser
Суть: http://packagist.org/packages/sabberworm/php-css-parser
Последнее обновление: 31 мая 2017 г. (если это указано, поскольку дата в записи блога может ввести вас в заблуждение, что она больше не обновляется.)

К сожалению, этот проект слишком силен. Из довольно простого CSS создает очень болтливую структуру. Также перед первым использованием вы должны иметь дело с composer (я сам в конечном итоге добавил require_once для каждого файла в parser.php).

2 голосов
/ 16 июля 2015

В дополнение к ответу Габриэля Андерсона на обработку запросов css @media, селектора дочерних элементов >, изображений base64 и input[type="button"]:hover

function parse_css_selectors($css,$media_queries=true){

    $result = $media_blocks = [];

    //---------------parse css media queries------------------

    if($media_queries==true){

        $media_blocks=parse_css_media_queries($css);
    }

    if(!empty($media_blocks)){

        //---------------get css blocks-----------------

        $css_blocks=$css;

        foreach($media_blocks as $media_block){

            $css_blocks=str_ireplace($media_block,'~£&#'.$media_block.'~£&#',$css_blocks);
        }

        $css_blocks=explode('~£&#',$css_blocks);

        //---------------parse css blocks-----------------

        $b=0;

        foreach($css_blocks as $css_block){

            preg_match('/(\@media[^\{]+)\{(.*)\}\s+/ims',$css_block,$block);

            if(isset($block[2])&&!empty($block[2])){

                $result[$block[1]]=parse_css_selectors($block[2],false);
            }
            else{

                $result[$b]=parse_css_selectors($css_block,false);
            }

            ++$b;
        }
    }
    else{

        //---------------escape base64 images------------------

        $css=preg_replace('/(data\:[^;]+);/i','$1~£&#',$css);

        //---------------parse css selectors------------------

        preg_match_all('/([^\{\}]+)\{([^\}]*)\}/ims', $css, $arr);

        foreach ($arr[0] as $i => $x){

            $selector = trim($arr[1][$i]);

            $rules = explode(';', trim($arr[2][$i]));

            $rules_arr = [];

            foreach($rules as $strRule){

                if(!empty($strRule)){

                    $rule = explode(":", $strRule,2);

                    if(isset($rule[1])){

                        $rules_arr[trim($rule[0])] = str_replace('~£&#',';',trim($rule[1]));
                    }
                    else{
                        //debug
                    }
                }
            }

            $selectors = explode(',', trim($selector));

            foreach ($selectors as $strSel){

                if($media_queries===true){

                    $result[$b][$strSel] = $rules_arr;
                }
                else{

                    $result[$strSel] = $rules_arr;
                }
            }
        }
    }
    return $result;
}

function parse_css_media_queries($css){

    $mediaBlocks = array();

    $start = 0;
    while(($start = strpos($css, "@media", $start)) !== false){

        // stack to manage brackets
        $s = array();

        // get the first opening bracket
        $i = strpos($css, "{", $start);

        // if $i is false, then there is probably a css syntax error
        if ($i !== false){

            // push bracket onto stack
            array_push($s, $css[$i]);

            // move past first bracket
            $i++;

            while (!empty($s)){

                // if the character is an opening bracket, push it onto the stack, otherwise pop the stack
                if ($css[$i] == "{"){

                    array_push($s, "{");
                }
                elseif ($css[$i] == "}"){

                    array_pop($s);
                }

                $i++;
            }

            // cut the media block out of the css and store
            $mediaBlocks[] = substr($css, $start, ($i + 1) - $start);

            // set the new $start to the end of the block
            $start = $i;
        }
    }

    return $mediaBlocks;
}

Ресурсы

2 голосов
/ 01 сентября 2010
<?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));

// увидеть то же самое

0 голосов
/ 01 сентября 2010

Вот быстрый и грязный автономный хак с использованием регулярных выражений:

$input = '
#stuff {
    background-color: red;
}

#content.postclass-subcontent {
    background-color: red;
}

#content2.postclass-subcontent2 {
    background-color: red;
}
';

$cssClassName = 'postclass';
preg_match_all('/(#[a-z0-9]*?\.?'.addcslashes($cssClassName, '-').'.*?)\s?\{/', $input, $matches);
var_dump($matches[1]);

Результат:

array(2) {
  [0]=>
  string(29) "#content.postclass-subcontent"
  [1]=>
  string(31) "#content2.postclass-subcontent2"
}
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...