2010-02-07 6 views
4

Avec des expressions régulières J'essaie de supprimer toutes les méthodes/fonctions du code suivant. Laissant la "portée globale" seule. Cependant, je n'arrive pas à le faire correspondre à tout le contenu interne d'une méthode.RegEx Suppression des méthodes du code

<?php 
$mother = new Mother(); 
class Hello 
{ 
    public function FunctionName($value="username",) 
    { 

    } 
    public function ododeqwdo($value='') 
    { 
     # code... 
    } 
    public function ofdoeqdoq($value='') 
    { 
    if(isset($mother)) { 
     echo $lol; 
    } 
    if(lol(9)) { 
     echo 'lol'; 
    } 
    } 
} 
function user() 
{ 
    if(isset($mother)) { 
     echo $lol; 
    } 
    if(lol(9)) { 
     echo 'lol'; 
    } 
} 
    $mother->global(); 
function asodaosdo() { 

} 

L'expression régulière actuelle j'est: (?:(public|protected|private|static)\s+)?function\s+\w+\(.*?\)\s+{.*?} Cependant, il ne sera pas choisir une méthode qui a crochets à l'intérieur, comme function user().

Si quelqu'un pouvait me diriger dans la bonne direction.

+0

Obtenez un analyseur.͏͏ – kennytm

+0

N'importe quel analyseur que vous connaissez me permettrait de le faire sans trop de problèmes? – MarioRicalde

Répondre

6

Vous ne pouvez pas le faire correctement avec regex. Vous devez écrire un analyseur capable d'analyser correctement les commentaires, les littéraux de chaîne et les parenthèses imbriquées.

Regex ne peut pas faire face à ces cas:

class Hello 
{ 
    function foo() 
    { 
    echo '} <- that is not the closing bracket!'; 
    // and this: } bracket isn't the closing bracket either! 
    /* 
    } and that one isn't as well... 
    */ 
    } 
} 

EDIT

Voici une petite démo de comment utiliser la fonction tokenizer mentionné par XUE Can:

$source = <<<BLOCK 
<?php 

\$mother = new Mother("this function isNotAFunction(\$x=0) {} foo bar"); 

class Hello 
{ 
    \$foo = 666; 

    public function FunctionName(\$value="username",) 
    { 

    } 
    private \$bar; 
    private function ododeqwdo(\$value='') 
    { 
     # code... 
    } 
    protected function ofdoeqdoq (\$value='') 
    { 
     if(isset(\$mother)) { 
      echo \$lol . 'function() {'; 
     } 
     if(lol(9)) { 
      echo 'lol'; 
     } 
    } 
} 

function user() 
{ 
    if(isset(\$mother)) { 
     echo \$lol; 
    } 
    /* comment inside */ 
    if(lol(9)) { 
     echo 'lol'; 
    } 
} 
/* comment to preserve function noFunction(){} */ 
\$mother->global(); 

function asodaosdo() { 

} 

?> 
BLOCK; 

if (!defined('T_ML_COMMENT')) { 
    define('T_ML_COMMENT', T_COMMENT); 
} 
else { 
    define('T_DOC_COMMENT', T_ML_COMMENT); 
} 

// Tokenize the source 
$tokens = token_get_all($source); 

// Some flags and counters 
$tFunction = false; 
$functionBracketBalance = 0; 
$buffer = ''; 

// Iterate over all tokens 
foreach ($tokens as $token) { 
    // Single-character tokens. 
    if(is_string($token)) { 
     if(!$tFunction) { 
      echo $token; 
     } 
     if($tFunction && $token == '{') { 
      // Increase the bracket-counter (not the class-brackets: `$tFunction` must be true!) 
      $functionBracketBalance++; 
     } 
     if($tFunction && $token == '}') { 
      // Decrease the bracket-counter (not the class-brackets: `$tFunction` must be true!) 
      $functionBracketBalance--; 
      if($functionBracketBalance == 0) { 
       // If it's the closing bracket of the function, reset `$tFunction` 
       $tFunction = false; 
      } 
     } 
    } 
    // Tokens consisting of (possibly) more than one character. 
    else { 
     list($id, $text) = $token; 
     switch ($id) { 
      case T_PUBLIC: 
      case T_PROTECTED: 
      case T_PRIVATE: 
       // Don'timmediately echo 'public', 'protected' or 'private' 
       // before we know if it's part of a variable or method. 
       $buffer = "$text "; 
       break; 
      case T_WHITESPACE: 
       // Only display spaces if we're outside a function. 
       if(!$tFunction) echo $text; 
       break; 
      case T_FUNCTION: 
       // If we encounter the keyword 'function', flip the `tFunction` flag to 
       // true and reset the `buffer` 
       $tFunction = true; 
       $buffer = ''; 
       break; 
      default: 
       // Echo all other tokens if we're not in a function and prepend a possible 
       // 'public', 'protected' or 'private' previously put in the `buffer`. 
       if(!$tFunction) { 
        echo "$buffer$text"; 
        $buffer = ''; 
       } 
     } 
    } 
} 

qui sera imprimer:

<?php 

$mother = new Mother("this function isNotAFunction($x=0) {} foo bar"); 

class Hello 
{ 
    $foo = 666; 


    private $bar; 


} 


/* comment to preserve function noFunction(){} */ 
$mother->global(); 



?> 

qui est la source d'origine, uniquement sans fonctions.

+0

Merci beaucoup d'avoir pris le temps de me donner un excellent exemple. +1 et réponse – MarioRicalde

+0

Vous êtes les bienvenus kuroir. Faire aussi voter XUE Peut répondre, si vous ne l'avez pas déjà fait: à cause de son post, j'ai posté cette petite démo. Étant novice en PHP, je n'ai jamais entendu parler de la fonction 'token_get_all (...)'. –

+0

Exemple cool! Merci, Bart. –

3

Je crois en utilisant PHP's built-in Tokenizer fonctionnalité ou Zend_CodeGenerator de Zend Framework est un moyen plus sûr. Ceux-ci garderont également votre code plus lisible. C'est juste parce que si vous voulez utiliser regexp pour analyser les codes source, vous devez maintenir votre propre ensemble de jetons, mais il y a une solution intégrée.

Questions connexes