2009-10-17 3 views
4

Я пишу быстрые preg_replace, чтобы вырезать комментарии из CSS. CSS комментарии обычно имеют следующий синтаксис:preg_replace out комментарии CSS?

/* Development Classes*/ 
/* Un-comment me for easy testing 
    (will make it simpler to see errors) */ 

Так что я пытаюсь убить все между/* и * /, например:

$pattern = "#/\*[^(\*/)]*\*/#"; 
$replace = ""; 
$v = preg_replace($pattern, $replace, $v); 

Нет кости! Кажется, он задыхается от косых черт, потому что я могу заставить его удалить текст комментариев, если я выберу/и из шаблона. Я попробовал несколько простых моделей, чтобы увидеть, если я мог бы просто потерять косую черту, но они возвращают исходную строку без изменений:

$pattern = "#/#"; 
$pattern = "/\//"; 

Любые идеи о том, почему я не могу показаться, чтобы соответствовать этим слэш? Благодаря!

+1

Я не буду предоставлять его в качестве ответа, поскольку он не применим непосредственно к вопросу, но есть некоторые хорошие инструменты, которые уже удаляют/уменьшают содержимое CSS: http://www.minifycss.com/ Просто для те, кто может быть здесь, пытаясь изобретать колесо :) – AvatarKava

+0

Вам лучше использовать парсер. В противном случае вы удалите что-то вроде 'content:"/* ... */"'. – Gumbo

+0

AvatarKara - Я действительно использую этот скрипт: http://code.google.com/p/cssmin/ - но по какой-то причине он не удалял комментарии. Я предположил, что мне придется написать этот бит в себе, но поскольку другие скрипты И ответы не работают, похоже, что что-то странное происходит ... Это для использования в плагине EE, поэтому мне интересно, если строка когда мне передают или окружают, есть некоторые причуды, о которых я не знаю. Спасибо за ссылку! –

ответ

11

Вот решение:

$regex = array(
"`^([\t\s]+)`ism"=>'', 
"`^\/\*(.+?)\*\/`ism"=>"", 
"`([\n\A;]+)\/\*(.+?)\*\/`ism"=>"$1", 
"`([\n\A;\s]+)//(.+?)[\n\r]`ism"=>"$1\n", 
"`(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+`ism"=>"\n" 
); 
$buffer = preg_replace(array_keys($regex),$regex,$buffer); 

Взятые из сценария/Stylesheet препроцессора в Samstyle PHP Framework

См: http://code.google.com/p/samstyle-php-framework/source/browse/trunk/sp.php

csstest.php:

<?php 

$buffer = file_get_contents('test.css'); 

$regex = array(
"`^([\t\s]+)`ism"=>'', 
"`^\/\*(.+?)\*\/`ism"=>"", 
"`([\n\A;]+)\/\*(.+?)\*\/`ism"=>"$1", 
"`([\n\A;\s]+)//(.+?)[\n\r]`ism"=>"$1\n", 
"`(^[\r\n]*|[\r\n]+)[\s\t]*[\r\n]+`ism"=>"\n" 
); 
$buffer = preg_replace(array_keys($regex),$regex,$buffer); 
echo $buffer; 

?> 

test.css:

/* testing to remove this */ 
.test{} 

Выход csstest.php:

.test{} 
+0

Это достало несколько пробелов и строк, но, похоже, оставило все комментарии неповрежденными.Это определенно похоже, что третья строка ДОЛЖНА удалять комментарии. Озадачивает. –

+0

привет, он отлично работает для меня - полностью. комментарии были удалены. – mauris

+0

Интересно! Спасибо за обновленный тест. Я запускаю это внутри плагина ExpressionEngine, поэтому я задаюсь вопросом, не вызывает ли какая-то разница в среде моих проблем. –

5

Я не верю, что вы можете использовать группировку в инверсный класса символов, как там у вас. То, что вы собираетесь использовать, называется Утверждения, из которых два типа. «смотреть вперед» и «смотреть сзади».

Образец, который вы ищете на английском языке, в основном, « косой чертой, буквенным шаблоном, чем-либо, за которым не следует прямая косая черта или что-либо иное, кроме буквенного шаблона, за которым следует косая черта или косая черта, которая не предшествует буквальным шаблоном ноля или более раз, буквальный джокер, слеш "

<?php 

$str = '/* one */ onemore 
/* 
* a 
* b 
**/ 
stuff // single line 
/**/'; 

preg_match_all('#/\*(?:.(?!/)|[^\*](?=/)|(?<!\*)/)*\*/#s', $str, $matches); 
print_r($matches); 

?> 
+0

Спасибо за подробное объяснение. Я не могу заставить это работать в файле, в котором я его использую, но он отлично работает, когда он изолирован, поэтому я подозреваю, что у меня больше проблем, чтобы выяснить ... –

0

Просто для удовольствия (и небольшого проекта, конечно) я сделал без регулярных выражений версии такой код (я надеюсь, что это быстрее):

function removeCommentFromCss($textContent) 
{ 
    $clearText = ""; 
    $charsInCss = strlen($textContent); 
    $searchForStart = true; 
    for($index = 0; $index < $charsInCss; $index++) 
    { 
     if ($searchForStart) 
     { 
      if ($textContent[ $index ] == "/" && (($index + 1) < $charsInCss) && $textContent[ $index + 1 ] == "*") 
      { 
       $searchForStart = false; 
       continue; 
      } 
      else 
      { 
       $clearText .= $textContent[ $index ]; 
      } 
     } 
     else 
     { 
      if ($textContent[ $index ] == "*" && (($index + 1) < $charsInCss) && $textContent[ $index + 1 ] == "/") 
      { 
       $searchForStart = true; 
       $index++; 
       continue; 
      } 
     } 
    } 
    return $clearText; 
}