fork(11) download
  1. <?php
  2.  
  3. function minify_css($str){
  4. # remove comments first (simplifies the other regex)
  5. $re1 = <<<'EOS'
  6. (?sx)
  7. # quotes
  8. (
  9. "(?:[^"\\]++|\\.)*+"
  10. | '(?:[^'\\]++|\\.)*+'
  11. )
  12. |
  13. # comments
  14. /\* (?> .*? \*/ )
  15. EOS;
  16.  
  17. $re2 = <<<'EOS'
  18. (?six)
  19. # quotes
  20. (
  21. "(?:[^"\\]++|\\.)*+"
  22. | '(?:[^'\\]++|\\.)*+'
  23. )
  24. |
  25. # ; before } (and the spaces after it while we're here)
  26. \s*+ ; \s*+ ( } ) \s*+
  27. |
  28. # all spaces around meta chars/operators
  29. \s*+ ( [*$~^|]?+= | [{};,>~+-] | !important\b ) \s*+
  30. |
  31. # spaces right of ( [ :
  32. ( [[(:] ) \s++
  33. |
  34. # spaces left of ) ]
  35. \s++ ( [])] )
  36. |
  37. # spaces left (and right) of :
  38. \s++ ( : ) \s*+
  39. # but not in selectors: not followed by a {
  40. (?!
  41. (?>
  42. [^{}"']++
  43. | "(?:[^"\\]++|\\.)*+"
  44. | '(?:[^'\\]++|\\.)*+'
  45. )*+
  46. {
  47. )
  48. |
  49. # spaces at beginning/end of string
  50. ^ \s++ | \s++ \z
  51. |
  52. # double spaces to single
  53. (\s)\s+
  54. EOS;
  55.  
  56. $str = preg_replace("%$re1%", '$1', $str);
  57. return preg_replace("%$re2%", '$1$2$3$4$5$6$7', $str);
  58. }
  59.  
  60.  
  61.  
  62. $in = <<<'EOS'
  63.  
  64. p * i , html
  65. /* remove spaces */
  66.  
  67. /* " comments have no escapes \*/
  68. body/* keep */ /* space */p,
  69. p [ remove ~= " spaces " ] :nth-child( 3 + 2n ) > b span i , div::after
  70.  
  71. {
  72. /* comment */
  73. background : url( " /* string */ " ) blue !important ;
  74. content : " escapes \" allowed \\" ;
  75. width: calc( 100% - 3em + 5px ) ;
  76. margin-top : 0;
  77. margin-bottom : 0;
  78. margin-left : 10px;
  79. margin-right : 10px;
  80. }
  81.  
  82. EOS;
  83.  
  84.  
  85. $out = minify_css($in);
  86.  
  87. echo "input:\n";
  88. var_dump($in);
  89.  
  90. echo "\n\n";
  91. echo "output:\n";
  92. var_dump($out);
  93.  
  94. ?>
Success #stdin #stdout 0.01s 20520KB
stdin
Standard input is empty
stdout
input:
string(435) "
p * i ,  html   
/* remove spaces */

/* " comments have no escapes \*/
body/* keep */ /* space */p,
p  [ remove ~= " spaces  " ]  :nth-child( 3 + 2n )  >  b span   i  ,   div::after

{
  /* comment */
    background :  url(  "  /* string */  " )   blue  !important ;
	content  :  " escapes \" allowed \\" ;
      width: calc( 100% - 3em + 5px ) ;
  margin-top : 0;
  margin-bottom : 0;
  margin-left : 10px;
  margin-right : 10px;
}
"


output:
string(251) "p * i,html body p,p [remove~=" spaces  "] :nth-child(3+2n)>b span i,div::after{background:url("  /* string */  ") blue!important;content:" escapes \" allowed \\";width:calc(100%-3em+5px);margin-top:0;margin-bottom:0;margin-left:10px;margin-right:10px}"