preg_replace out CSS comments?

后端 未结 4 571
一整个雨季
一整个雨季 2020-12-10 16:12

I\'m writing a quick preg_replace to strip comments from CSS. CSS comments usually have this syntax:

/* Development Classes*/
/* Un-comment me for easy testi         


        
相关标签:
4条回答
  • 2020-12-10 16:56

    Just for fun(and small project of course) I made a non-regexp version of a such code (I hope it's faster):

    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;
    }
    
    0 讨论(0)
  • 2020-12-10 16:59

    I don't believe you can use grouping within a negated character class like you have there. What you're going to want to use is called Assertions, of which there are two types. "look-ahead" and "look-behind".

    The pattern you're looking for in English is basically, "forward slash, literal wildcard, anything that isn't followed by a forward slash or anything other than a literal wildcard that is followed by a forward slash or a forward slash that isn't preceded by a literal wildcard zero or more times, literal wild card, forward slash"

    <?php
    
    $str = '/* one */ onemore
    /*
    * a
    * b
    **/
    stuff // single line
    /**/';
    
    preg_match_all('#/\*(?:.(?!/)|[^\*](?=/)|(?<!\*)/)*\*/#s', $str, $matches);
    print_r($matches);
    
    ?>
    
    0 讨论(0)
  • 2020-12-10 17:03

    Here's a solution:

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

    Taken from the Script/Stylesheet Pre-Processor in Samstyle PHP Framework

    See: 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{}
    

    Output of csstest.php:

    .test{}
    
    0 讨论(0)
  • 2020-12-10 17:06

    I had the same issue. To solve it, I first simplified the code by replacing "/ASTERIX" and "ASTERIX/" with different identifiers and then used those as the start and end markers.

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

    The /s flag tells the search to go onto new lines

    0 讨论(0)
提交回复
热议问题