2009-10-17 8 views
4

J'écris un preg_replace rapide pour enlever les commentaires de CSS. commentaires CSS ont généralement cette syntaxe:preg_replace des commentaires CSS?

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

Je suis en train de tuer tout entre/* et * /, comme ceci:

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

Pas de dés! Il semble étouffer sur les barres obliques, parce que je peux l'obtenir pour enlever le texte des commentaires si je sors le/s hors du modèle. J'ai essayé quelques modèles plus simples pour voir si je pouvais perdre les barres obliques, mais ils retournent la chaîne d'origine inchangée:

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

Toutes les idées sur la raison pour laquelle je ne peux pas sembler correspondre à ces barres obliques? Merci!

+1

Je ne vais pas le fournir comme une réponse, car il ne s'applique pas vraiment directement à la question, mais il existe de bons outils qui suppriment/réduisent déjà le contenu CSS: http://www.minifycss.com/ ceux qui pourraient être ici essayant de réinventer la roue :) – AvatarKava

+0

Vous devriez mieux utiliser un analyseur. Sinon, vous supprimerez quelque chose comme 'content:"/* ... */"'. – Gumbo

+0

AvatarKara - J'utilise actuellement ce script: http://code.google.com/p/cssmin/ - mais il ne supprimait pas les commentaires pour une raison quelconque. J'ai supposé que je devrais écrire ce peu en moi-même, mais comme d'autres scripts ET réponses ne fonctionnent pas, il semble que quelque chose d'étrange se passe ... Ceci est pour une utilisation dans un plugin EE, donc je me demande si la chaîne être passé ou l'environnement ont des bizarreries dont je ne suis pas au courant. Merci pour le lien! –

Répondre

11

Voici une 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); 

Tiré du script/feuille de style pré-processeur dans Samstyle PHP Framework

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

Sortie de csstest.php:

.test{} 
+0

Cela a pris des espaces et des sauts de ligne, mais a semblé laisser tous les commentaires intacts.Il semble vraiment que la troisième ligne DEVRAIT supprimer les commentaires, cependant. Déconcertant. –

+0

Salut là-bas, ça marche bien pour moi - totalement. les commentaires ont tous été supprimés. – mauris

+0

Intéressant! Merci pour le test mis à jour. Je cours cela dans un plugin ExpressionEngine, donc je me demande si une différence d'environnement cause mes problèmes. –

5

Je ne crois pas que vous pouvez utiliser le regroupement au sein d'une classe de caractères niée comme vous avez là. Ce que vous allez vouloir utiliser est appelé Assertions, dont il existe deux types. "look-ahead" et "look-behind". Le motif que vous cherchez en anglais est fondamentalement " barre oblique, caractère générique littéral, tout ce qui n'est pas suivi d'une barre oblique ou autre chose qu'un caractère générique littéral qui est suivi d'une barre oblique ou d'un slash qui n'est pas précédé d'un caractère générique littéral zéro ou plusieurs fois, wild card littérale, barre oblique "

<?php 

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

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

?> 
+0

Merci pour l'explication en profondeur. Je n'arrive pas à faire fonctionner ce fichier dans le fichier dans lequel je l'utilise, mais il fonctionne parfaitement lorsqu'il est isolé, donc je suppose que j'ai plus de problèmes à résoudre ... –

0

Juste pour le plaisir (et petit projet bien sûr) j'ai fait une version non-regexp d'un un tel code (j'espère que c'est plus rapide):

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; 
} 
Questions connexes