2013-02-11 14 views
1

我想從使用php的css文件中提取顏色。 這些顏色可以是:使用PHP從css文件中提取顏色

  1. 正常顏色(顏色:#XXXXXX)
  2. 背景顏色(背景:#XXXXXX; /背景:... #XXXXXX ...;)
  3. 背景梯度(背景圖像:線性梯度(頂部,#XXXXXX,#XXXXXX);
  4. 有時顏色可以是3個字符(例如:#FFF)

我試圖預浸匹配返回話,從第

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

...但它也返回DIV IDS(的#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); 
+1

如果展開你的表達,包括結腸,應該照顧的div編號 – 2013-02-11 19:16:28

+0

@JeffHawthorne我想過了,但有時在「:」和「#」之間可能會有一個或多個空格 - 另外,我認爲它不會涵蓋我的需求列表的案例2和3,糾正我,如果我錯了 - 我是在寫這些表達方式的時候不是親! – Romit 2013-02-11 19:31:25

+0

我其實剛剛讀到這個。你可以使用「:*#」來告訴它處理冒號和#之間的任意數量的空格。星號表示0到n次,如果知道至少有一個空格,則加號會起作用 – 2013-02-11 19:36:18

回答

1

既然你只接受3個或6個十六進制字符,我想這正則表達式可以更準確:

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

但是,這些字符的ID也會匹配。因此,我不建議使用正則表達式來解決這個問題。

+0

我明白你不使用正則表達式的建議,你可以參考問題中的'編輯1',並推動我在這一個? – Romit 2013-02-11 20:04:04

+0

它幾乎是相同的,你只需要添加一個或冒號和分號在末尾:'/(?!\ b)((#[0-9abcdef] {3} |#[0-9abcdef] {6})(\ b |; |,))/' – 2013-02-11 20:26:31

+0

實際上,因爲顏色可以在shorthands和專有的選擇器內進行,另外,你需要首先檢查6,否則它不會匹配 – runspired 2013-02-11 21:53:42

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; 
     } 
    } 
} 
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 
} 
+0

也有,並刪除空白以確保它不會混淆和模式匹配。例如。 'preg_replace('/ \ s/g','',$ css_text);' – runspired 2013-02-11 21:57:58

+0

謝謝,看起來真不錯!但我得到「未知修飾符'g'」錯誤與preg_match – Romit 2013-02-13 06:31:54

+0

只是將其更改爲preg_match_all並刪除g,我忘了PHP不允許g修飾符,因爲它們將全局分隔成一個單獨的函數 – runspired 2013-02-13 07:47:40