用 PHP 解析 CSS 文件

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3618381/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 10:26:34  来源:igfitidea点击:

Parse a CSS file with PHP

phpcssregexparsing

提问by stefan

I want to parse (in a special way) a CSS file with PHP.

我想用 PHP 解析(以特殊方式)一个 CSS 文件。

Example:

例子:

cssfile.css:

cssfile.css

#stuff {
    background-color: red;
}

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

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

And I want that PHP returns me each class name that have the postclass in its name.

而且我希望 PHP 返回每个名称中包含 postclass 的类名。

The result look like an array having in this example:

结果看起来像这个例子中的一个数组:

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

But I'm worse at regular expressions. somehow search for "postclass" and then grap the hole line and put into an array.

但我更擅长正则表达式。以某种方式搜索“postclass”,然后抓住孔线并放入一个数组中。



thank you and i used it to parse a css file simliar to a confic file.

谢谢你,我用它来解析一个类似于 confic 文件的 css 文件。

$(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] + '" />');
            });
        }
    });
});

was my final code. so i can wrap easily a div around some hardcode-html without editing the layout. so i just have to edit my cssfile and add there something like

是我的最终代码。所以我可以在不编辑布局的情况下轻松地将 div 包裹在一些 hardcode-html 周围。所以我只需要编辑我的 cssfile 并在那里添加类似的东西

id .postclass-class { some styles }

id .postclass-class { 一些样式 }

and my code searchs for the id and wraps the inner content with an div. i needed that for quickfixes when i just have to add a div around something for a clear or a background.

我的代码搜索 id 并用 div 包装内部内容。当我只需要在某些东西周围添加一个 div 以获得清晰或背景时,我需要它来进行快速修复。

采纳答案by softcr

Here is a quick and dirty standalone hack using regex:

这是使用正则表达式的快速而肮脏的独立黑客:

$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]);

Results in:

结果是:

array(2) {
  [0]=>
  string(29) "#content.postclass-subcontent"
  [1]=>
  string(31) "#content2.postclass-subcontent2"
}

回答by shamittomar

There is a very good CSS parser classin PHP. Use it. Here is its sample code:

PHP 中有一个非常好的CSS 解析器类。用它。这是它的示例代码:

<?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
?> 

回答by Gabriel Anderson

I found a solution:

我找到了一个解决方案:

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');

use:

用:

$css['#selector']['color'];

回答by sumid

Just for completeness there is also another library for parsing CSS: sabberworm / PHP-CSS-Parser.

Homepage: http://www.sabberworm.com/blog/2010/6/10/php-css-parser
GitHub: http://github.com/sabberworm/PHP-CSS-Parser
Gist: http://packagist.org/packages/sabberworm/php-css-parser
Last update: May 31, 2017 (Stating this because the date in the blog entry may mislead you that it isn't updated anymore.)

Unfortunately this project is bit too robust. From quite simple CSS creates very chatty structure. Also before first use you have to deal with composer (I myself did end-up adding require_once for each file into parser.php).

为了完整起见,还有另一个用于解析 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
最后更新:2017 年 5 月 31 日(之所以这样说是因为博客条目中的日期可能会误导您它不再更新。)

不幸的是,这个项目有点太健壮了。从非常简单的 CSS 创建非常健谈的结构。同样在第一次使用之前,你必须处理作曲家(我自己最终将每个文件的 require_once 添加到 parser.php 中)。

回答by Pramendra Gupta

<?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));

//see its same

//看到它一样

回答by RafaSashi

In addition to Gabriel Anderson's answer to handle css @media queries, child selector >,base64 images, and input[type="button"]:hover

除了 Gabriel Anderson 处理 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','~£&#',$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;
}

Resources

资源