preg_replace出CSS评论?

时间:2009-10-17 00:37:24

标签: php regex preg-replace

我正在编写一个快速preg_replace来从CSS中删除注释。 CSS注释通常具有以下语法:

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

所以我试图杀死/ *和* /之间的所有内容,如下所示:

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

没有骰子!它似乎在正斜杠上窒息,因为如果我将/ s取出模式,我可以删除注释文本。我尝试了一些更简单的模式,看看我是否可以丢失斜杠,但它们会保持原始字符串不变:

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

为什么我似乎无法匹配这些斜杠的任何想法?谢谢!

5 个答案:

答案 0 :(得分:13)

这是一个解决方案:

$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);

取自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{}

答案 1 :(得分:5)

我不相信你可以在一个否定的角色类中使用分组,就像你在那里一样。您将要使用的内容称为断言,其中有两种类型。 “向前看”和“向后看”。

你用英语寻找的模式基本上是,“正斜杠,字面通配符,任何没有正斜杠或任何除了字面通配符之外的东西,后跟正斜杠或一个前向斜杠,前面没有文字通配符零次或多次,字面外卡,正斜杠

<?php

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

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

?>

答案 2 :(得分: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;
}

答案 3 :(得分:0)

我有同样的问题。 为了解决该问题,我首先通过用不同的标识符替换“ / ASTERIX”和“ ASTERIX /”来简化代码,然后将它们用作开始和结束标记。

$code = str_replace("/*","_COMSTART",$code);
$code = str_replace("*/","COMEND_",$code);
$code = preg_replace("/_COMSTART.*?COMEND_/s","",$code);

/ s标志指示搜索进入新行

答案 4 :(得分:0)

PHP 7.3更新

接受的答案对我不起作用。对我有用的是

$commentLess = preg_replace( '!/\*[^*]*\*+([^/][^*]*\*+)*/!' , '' , $commentFull );