我正在编写一个快速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 = "/\//";
为什么我似乎无法匹配这些斜杠的任何想法?谢谢!
答案 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 );