regex 使用PHP解析CSS文件

laximzn5  于 2022-11-18  发布在  PHP
关注(0)|答案(7)|浏览(155)

我想用PHP解析(以一种特殊的方式)一个CSS文件。
示例:
cssfile.css

#stuff {
    background-color: red;
}

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

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

我希望PHP返回名称中包含postclass的每个类名。
在本例中,结果看起来像一个数组,其中包含:

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

但是我在正则表达式方面更差。不知何故搜索“postclass”,然后用图形表示洞线并放入数组中。
谢谢,我用它来解析一个类似于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] + '" />');
            });
        }
    });
});

是我最后的代码。所以我可以很容易地用一个div包裹一些硬代码-html,而不需要编辑布局。所以我只需要编辑我的cssfile并在那里添加一些东西,比如

id .postclass-class {某些样式}

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

j0pj023g

j0pj023g1#

PHP中有一个非常好的CSS parser class。使用它。下面是它的示例代码:

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

c6ubokkw2#

我找到了解决办法:

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'];
qyyhg6bp

qyyhg6bp3#

为了完整起见,还有另一个用于解析CSS的库:Sabberworm / PHP-CSS解析器.
首页: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创建非常健谈的结构。而且在第一次使用之前,你必须处理composer(我自己最终为每个文件添加了require_once到parser.php)。

i7uq4tfw

i7uq4tfw4#

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

数据类型

jslywgbw

jslywgbw5#

除了Gabriel安德森对处理css @媒体查询的回答之外,子选择器>、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;
}

资源

mi7gmzs6

mi7gmzs66#

这里是一个快速和肮脏的独立黑客使用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]);

结果:

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

dsf9zpds7#

我 正在 寻找 一 个 函数 来 读取 css 数据 ( 字符 串 或 文件 ) 。

      • 此处 列出 的 所有 解决 方案 都 很 棒 ! ! ! * * *

但 对 我 最 有用 的 函数 是 fromGabriel Anderson
我 重新 命名 了 这个 函数 , 并 对 它 进行 了 一些 扩展 , 包括 curly brake 等等 。 这个 函数 现在 能够 读取 带有 css 内容 的 文件 或 字符 串 。
错误 的 css 数据 会 生成 错误 消息 , 这些 错误 消息 会 输出 到 键 * ' debug-errors - cssreader ' * 下 。
1.如果 弯曲 制动 器 不 相等 , 则 会 出现 错误 消息 。
1.如果 它 是 一 个 文件 , 但 它 不 存在 , 则 会 出现 一 条 错误 消息 。
1.如果 字符 串 为 空 ( 字符 串 或 文件 名 ) , 也 一样 。
您 还 可以 使用 regExp 搜索 模式 来 过滤 输出 。

$cssStr = 'path/to/file.css';      // or CSS code
$returnSelectorOnly = true;        // (optional) return css selector only
$regExpFilter = '/(your regExp)/'; // your (preg_match) pattern

$css = cssReader($cssStr, $returnSelectorOnly, $regExpFilter);

中 的 每 一 个
我 还 对 它 进行 了 扩展 , 使 您 只能 在 数组 中 显示 选择 器 。
例如 , 我 使用 函数 读取 icofont/fontawesome css 文件 , 我 只 输出 css 选择 器 并 进一步 处理 它们 。
因此 , 我 编写 了 概述 页面 , 以 查看 可用 的 图标 。
这里 举 一 个 小 例子

$css = cssReader('icofont.css', true, '/(.icofont-)(.*?)(:before)/');
echo "<pre>";
echo var_dump($css);
echo "</pre>";

格式
输出 量

array(2105) {
  [0]=>
  string(29) ".icofont-angry-monster:before"
  [1]=>
  string(23) ".icofont-bathtub:before"
  [2]=>
  string(26) ".icofont-bird-wings:before"
  [3]=>
  string(19) ".icofont-bow:before"
  [4]=>
  string(25) ".icofont-brain-alt:before"
  [5]=>
  string(29) ".icofont-butterfly-alt:before"
  [6]=>
  string(22) ".icofont-castle:before"
  [7]=>
  string(23) ".icofont-circuit:before"
  [8]=>
  string(20) ".icofont-dart:before"
  [9]=>
  string(24) ".icofont-dice-alt:before"

...

}

格式
也许 其他 人 和 我 一样 需要 这个 函数 , 下面 我 把 整个 函数 包括 在 例子 中 。

    • 再次 感谢 您 提供 的 强大 功能 ! * *
function cssReader($cssStr, $returnSelectorOnly = false, $regExpFilter = "") {
    $css = false;
    $result = array();
    $error = array();
    $debug = true;
    $isfile = false;
    $filename = @trim(@pathinfo($cssStr)['filename']);
    if ($cssStr != "" && $filename != "") {
        $isfile = true;
    }
    // checking for is file and file exists
    if (is_file($cssStr)) {
        $cssStr = file_get_contents($cssStr);
        $countCurlyBrakes_open = substr_count($cssStr, "{");
        $countCurlyBrakes_close = substr_count($cssStr, "}");
        if ($countCurlyBrakes_open && $countCurlyBrakes_close) {
            if ($countCurlyBrakes_open == $countCurlyBrakes_close) {
                $css = $cssStr;
            } else {
                // debug        
                $error[] = "#1 File error: The counting of '{' or '}' was different, '{' = ".$countCurlyBrakes_open." and '}' = ".$countCurlyBrakes_close.".";
            }
        } else {
            // debug        
            $error[] = "#2 File error: Curly braces error, the counting of '{' or '}' was 0 (zero).";
        }
    } else {
        if ($isfile) {
            // debug 
            $error[] = "#3 File error: '".$cssStr."' the file does not exist.";
        }
    }
    // checking for is not a file and has no file extension and is shorter than 2049 characters
    // !!! // Technically speaking, your URL should never be longer than 2,048 characters. Any long than this and Internet Explorer won’t be able to load your page
    if (!$isfile) {
        if (!empty($cssStr)) {
            $countCurlyBrakes_open = substr_count($cssStr, "{");
            $countCurlyBrakes_close = substr_count($cssStr, "}");
            if ($countCurlyBrakes_open && $countCurlyBrakes_close) {
                if ($countCurlyBrakes_open == $countCurlyBrakes_close) {
                    $css = $cssStr;
                } else {
                    // debug        
                    $error[] = "#4 String error: The counting of '{' or '}' was different, '{' = ".$countCurlyBrakes_open." and '}' = ".$countCurlyBrakes_close.".";
                }
            } else {
                // debug        
                $error[] = "#5 String error: Curly braces error, the counting of '{' or '}' was 0 (zero).";
            }
        } else {
            // debug
            $error[] = "#6 String error: (string) $cssStr was empty.";
        }
    }
    // place errors on top of the array
    if ($debug && count($error)) {
        $result['debug-errors-cssreader'] = $error;
    }
    $regExp = "/(?ims)([a-z0-9\s\.\:#_\-@,]+)\{([^\}]*)\}/";
    preg_match_all(''.$regExp.'', $css, $arr);
    foreach ($arr[0] as $i => $x){
        $selector = trim($arr[1][$i]);
        if ($returnSelectorOnly == false || $returnSelectorOnly == "" || !$returnSelectorOnly) {
            $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){
            if ($returnSelectorOnly == false || $returnSelectorOnly == "" || !$returnSelectorOnly) {
                $result[$strSel] = $rules_arr;
            } else {
                if ($regExpFilter == false || $regExpFilter == "" || !$regExpFilter) {
                    $result[] = $strSel;
                } else {
                    if (preg_match($regExpFilter, $strSel)) {
                        $result[] = $strSel;
                    }
                }
            }
        }
    }
    return $result;
}

$css = cssReader('icofont.css', true, '/(.icofont-)(.*?)(:before)/');
echo "<pre>";
echo var_dump($css);
echo "</pre>";

格式

相关问题