【问题标题】:Extract colors from css file using PHP使用 PHP 从 css 文件中提取颜色
【发布时间】:2013-02-11 19:11:47
【问题描述】:

我正在尝试使用 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);

【问题讨论】:

  • 如果你扩展你的表达式以包含冒号,那应该注意 div id
  • @JeffHawthorne 我考虑过,但有时“:”和“#”之间可能有一个或多个空格 - 另外,我认为它不会涵盖我的需求列表的案例 2 和 3,正确如果我错了,我 - 我不是写这些表达的专家!
  • 我实际上只是在阅读这方面的内容。您可以使用“:*#”来告诉它处理冒号和#之间的任意数量的空格。星号表示 0 到 n 次,如果您知道至少会有一个空格,则加号有效
  • @JeffHawthorne 明白了。但是如果我们有 [background: url() #xxx;] 或 [background-image: linear-gradient(top, #xxxxxx, #xxxxxx] ??
  • 对了,你是不是也需要找rgbacolors...?例如 - 请参阅您的 css 示例输出的第 38 行末尾。

标签: php javascript search preg-match extract


【解决方案1】:

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

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

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

【讨论】:

  • 我理解您关于不使用正则表达式的建议,您能否在问题中参考“编辑 1”并推动我继续这个问题?
  • 几乎一样,只需要在最后的冒号和分号加上OR即可:/(?!\b)((#[0-9abcdef]{3}|#[0-9abcdef]{6})(\b|;|,))/
  • 实际上这不起作用,因为颜色可以在速记和专有选择器中。此外,您需要先检查 6,否则它将不匹配。
【解决方案2】:

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

第 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
}

【讨论】:

  • 另外,有时最好继续去掉空格以确保它不会弄乱和模式匹配。例如。 preg_replace('/\s/g','',$css_text);
  • 谢谢,看起来真不错!但是我收到 preg_match 的“未知修饰符 'g'”错误
  • 只需将其更改为 preg_match_all 并删除 g,我忘记了 PHP 不允许 g 修饰符,因为它们将全局分隔为单独的函数
【解决方案3】:

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

【讨论】:

    猜你喜欢
    • 2021-05-14
    • 1970-01-01
    • 2013-05-16
    • 1970-01-01
    • 1970-01-01
    • 2022-01-06
    • 2014-05-13
    • 2019-04-30
    • 1970-01-01
    相关资源
    最近更新 更多