使用PHP从css文件中提取颜色

使用PHP从css文件中提取颜色,php,javascript,search,preg-match,extract,Php,Javascript,Search,Preg Match,Extract,我正在尝试使用php从css文件中提取颜色。 这些颜色可能是: 正常颜色(颜色:#xxxxxx;) 背景色(背景:#xxxxxx;/background:…#xxxxxx…) 背景渐变(背景图像:线性渐变(顶部,#xxxxxx,#xxxxxx) 有时颜色可能是3个字符(例如:#fff) 我尝试preg match返回以# …但它也返回DIV id(#header等) 接下来,我还希望我们的代码返回一个多维数组,不仅包含颜色代码,还包含找到它的行号 请帮忙!:) ----------编辑:问题解决

我正在尝试使用php从css文件中提取颜色。 这些颜色可能是:

  • 正常颜色(颜色:#xxxxxx;)
  • 背景色(背景:#xxxxxx;/background:…#xxxxxx…)
  • 背景渐变(背景图像:线性渐变(顶部,#xxxxxx,#xxxxxx)
  • 有时颜色可能是3个字符(例如:#fff)
  • 我尝试preg match返回以#

    …但它也返回DIV id(#header等)

    接下来,我还希望我们的代码返回一个多维数组,不仅包含颜色代码,还包含找到它的行号

    请帮忙!:)

    ----------编辑:问题解决了----------

    谢谢大家的回答,我把每个人的答案都结合起来了。 由于我希望将正则表达式保持在最小值,这是我用作最终工作代码的代码:

    $css = file_get_contents("style.css");
    
    $token = strtok($css, "{}");
    $css_parts = array();
    while ($token !== false) {
        $css_parts[] = trim($token);
        $token = strtok("{}");
    }
    
    $flag = false; $properties = "";
        foreach($css_parts as $part) {
        if($flag) { $properties .= " ".trim($part); }
        $flag = !$flag;
    }
    $properties = strtoupper(str_replace(array(":",",",";","(",")")," ",$properties));
    
    $colors = array();
    preg_match_all('/(?!\b)(#\w+\b)/',$properties,$colors);
    $colors = array_unique($colors[0]);
    
    print_r($colors);
    

    由于您只接受3或6个十六进制字符,因此我认为此正则表达式可能更准确:

    /(?!\b)((#[0-9abcdef]{3}|#[0-9abcdef]{6})\b)/
    

    但是,具有这些字符的ID也将被匹配。因此,我不建议使用正则表达式来解决这个问题。

    这里有一些代码不使用正则表达式(它在行和字符上循环),但可以完成这项工作。它生成一个关联数组,其中键是十六进制颜色代码,值是找到颜色键的行号数组。(也可以修改为包含rgba颜色键)

    $lst\u行=数组(
    35=>“颜色:#000;文字装饰:无;”,
    36=>“字体大小:2.5em;”,
    37=>“边距顶部:5px;线条高度:60px;高度:60px;浮动:右侧;边框半径:5px;方框-阴影:插图0px 0px 1px#872424,插图0px 2px 0px 0px 0px#F79494,插图0px 0px 0px 2px#E78484;背景:#A7444;背景图像:线性渐变(顶部,#A7444,35444);背景图像:线性渐变(顶部,35444,35444);背景图像:-webkit线性渐变(顶部,#A7444,#C76464);背景图像:-o线性渐变(顶部,#A7444,#C76464);背景图像:-ms线性渐变(顶部,#A7444,#C76464);文本阴影:-1px-1px 0px rgba(0,0,0.5);“,
    38=>“颜色:#1d;文本转换:大写;字体大小:1.1em;字母间距:-1px;文本装饰:无;颜色:#fff;不透明度:0.6;过滤器:alpha(不透明度=50');”,
    );
    //返回$int\U位置处$str\U行中的颜色
    函数findColor($int\u pos,$str\u line){
    $str_temp=substr($str_line,$int_pos,6);
    $lst_temp=str_split($str_temp);
    $lst_end=array(“,”,“;”,“),“},”;
    $hex_color='#';
    foreach($i=>c){
    如果(!in_数组($c,$lst_end)和($i<6))$hex_color.=$c;
    否则就断了;
    }
    返回$hex_颜色;
    }
    $arr_colors=array();//这是输出数组
    foreach($int\u-no=>$str\u-line){
    $lst_chars=str_split($str_line);
    foreach($i=>c){
    如果($c='#'){
    $hex\u col=findColor($i+1,$str\u line);
    $arr\u colors[$hex\u col][]=$int\u no;
    }
    }
    }
    
    实际上,只要假设选择器中没有花括号(通常是一个很好的假设),就可以很容易地用三管齐下的方法实现这一点

    步骤1:获取{}内的内容

    preg_match( '/\{([^\}]*)\}/gi' , $css_text , $lines );
    
    第二步:抓取颜色

    $colors = array();
    $i = sizeof($lines);
    
    while( $i-- ) {
        preg_match( '/(#[0-9a-f]{6}|#[0-9a-f]{3})/' , $line[$i] , $matches );
        $colors += $matches; //combine the arrays
    }
    

    如果将表达式扩展为包含冒号,则应考虑divids@JeffHawthorne我想了想,但有时在“:”和“#”之间可能有一个或多个空格-而且,我认为它不会涵盖我的需求列表中的案例2和案例3,如果我错了,请纠正我-我不擅长编写这些表达式!事实上,我刚刚读过这篇文章。您可以使用“:*#”命令它处理冒号和#之间的任意数量的空格。星号表示0到n次,如果您知道至少会有一个加号,则加号有效space@JeffHawthorne理解。但如果我们有[background:url()#xxx;]或[background image:linear gradient(顶部,#xxxxxx,#xxxxxx]?顺便问一下,你不需要找到
    rgba
    颜色吗…?例如,请参阅css示例输出的第38行末尾。我理解你关于不使用正则表达式的建议,你能在问题中参考“编辑1”并在这一点上推动我吗?几乎是一样的,你只需在结尾处为冒号和分号添加OR:
    /(?!\b)((#[0-9abcdef]{3}|#[0-9abcdef]{6})(\b | |,)/
    实际上,这不起作用,因为颜色可以在速记和专有选择器中进行选择。此外,您需要先检查6,否则它将不匹配。此外,有时最好先去掉空白,以确保它不会弄乱和模式匹配。例如,
    preg_replace('/\s/g','.$css_text)
    谢谢,看起来真的很好!但是我在preg_match中遇到了“Unknown modifier'g'”错误。只需将其更改为preg_match_all并删除g,我忘记了PHP不允许使用g修饰符,因为它们将全局修饰符分隔为单独的函数
    preg_match( '/\{([^\}]*)\}/gi' , $css_text , $lines );
    
    $colors = array();
    $i = sizeof($lines);
    
    while( $i-- ) {
        preg_match( '/(#[0-9a-f]{6}|#[0-9a-f]{3})/' , $line[$i] , $matches );
        $colors += $matches; //combine the arrays
    }