使用PHP从css文件中提取颜色
我正在尝试使用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等) 接下来,我还希望我们的代码返回一个多维数组,不仅包含颜色代码,还包含找到它的行号 请帮忙!:) ----------编辑:问题解决
$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
}