1

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

  1. 正常颜色(颜色:#xxxxxx;)
  2. 背景颜色(背景:#xxxxxx;/背景:...#xxxxxx ...;)
  3. 背景渐变(背景图像:线性渐变(顶部,#xxxxxx,#xxxxxx);
  4. 有时颜色可能是 3 个字符(例如:#fff)

我尝试使用 preg match 返回以 # 开头的单词

preg_match_all('/(?!\b)(#\w+\b)/', $css_text, $matches)

...但它也返回 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);
4

3 回答 3

1

实际上,只要您假设选择器中没有大括号(通常是一个很好的假设),您就可以很容易地使用三管齐下的方法来做到这一点。

第 1 步:抓取 {} 内的内容

preg_match( '/\{([^\}]*)\}/gi' , $css_text , $lines );

第2步:抓取颜色

$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
}
于 2013-02-11T21:44:04.143 回答
1

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

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

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

于 2013-02-11T19:34:29.960 回答
0

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

$lst_lines = array(
   35 => "color: #000;text-decoration: none;",
   36 => "font-size: 2.5em;",
   37 => "margin-top: 5px;line-height: 60px;height: 60px;float: right;border-radius: 5px;box-  shadow: inset 0px 0px 0px 1px #872424, inset 0px 2px 0px 0px #F79494, inset 0px 0px 0px 2px #E78484;background: #A74444;background-image: linear-gradient(top, #A74444, #C76464);background-image: -moz-linear-gradient(top, #A74444, #C76464);background-image: -webkit-linear-gradient(top, #A74444, #C76464);background-image: -o-linear-gradient(top, #A74444, #C76464);background-image: -ms-linear-gradient(top, #A74444, #C76464);text-shadow: -1px -1px 0px rgba(0,0,0,0.5);",
   38 => "color: #1D1D1D;text-transform: uppercase;font-size: 1.1em;letter-spacing: -1px;text-decoration: none;color: #fff;opacity: 0.6;filter:alpha(opacity='50');",
);

// returns color in $str_line at position $int_pos
function findColor($int_pos, $str_line) {
    $str_temp = substr($str_line, $int_pos, 6);
    $lst_temp = str_split($str_temp);
    $lst_end = array(',', ';', ')', '}', ' ');
    $hex_color = '#';
    foreach ($lst_temp as $i => $c) {
        if (!in_array($c, $lst_end) && ($i < 6)) $hex_color .= $c;
        else break;
    }
    return $hex_color;
}

$arr_colors = array();    // This is the output array
foreach ($lst_lines as $int_no => $str_line) {
    $lst_chars = str_split($str_line);
    foreach ($lst_chars as $i => $c) {
        if ($c == '#') {
            $hex_col = findColor($i+1, $str_line);
            $arr_colors[$hex_col][] = $int_no;
        }
    }
}
于 2013-02-11T20:58:21.887 回答