2010-02-07 6 views
4

정규식으로 다음 코드에서 모든 메서드/함수를 제거하려고합니다. "범 세계적인 범위"를 혼자 남겨 두는 것. 그러나 메서드의 모든 내부 내용에 일치하도록 관리 할 수는 없습니다.RegEx 코드에서 메서드 제거

<?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() { 

} 

내가 가진 현재의 정규 표현식은 다음과 같습니다 (?:(public|protected|private|static)\s+)?function\s+\w+\(.*?\)\s+{.*?}는 그러나, function user()처럼 괄호 안에이있는 방법을 선택하지 않습니다.

누군가가 올바른 방향으로 나를 가리킬 수 있다면.

+0

파서 가져 오기 – kennytm

+0

많은 문제없이이 작업을 수행 할 수있는 파서를 알고 계십니까? – MarioRicalde

답변

6

정규식으로는 올바르게 수행 할 수 없습니다. 주석, 문자열 리터럴 및 중첩 대괄호를 올바르게 구문 분석 할 수있는 파서를 작성해야합니다.

정규식은 이러한 경우에 대처 할 수 없습니다

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... 
    */ 
    } 
} 

편집

을 여기 XUE 언급 토크 나이 기능을 사용하는 방법에 약간의 데모의 수 :

$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 = ''; 
       } 
     } 
    } 
} 

하는 것 인쇄물 :

<?php 

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

class Hello 
{ 
    $foo = 666; 


    private $bar; 


} 


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



?> 

원래 소스이며 함수가 없어도됩니다.

+0

실례를 들어 주셔서 감사합니다. +1 그리고 답변 – MarioRicalde

+0

당신은 쿠로어를 환영합니다. XUE를 업 투표하십시오. 아직 완료하지 않았다면 대답 할 수 있습니다. 그의 게시물 때문에, 나는 그 작은 데모를 게시했습니다. PHP 초심자이기 때문에 나는'token_get_all (...) '함수에 대해 들어 본 적이 없다. –

+0

멋진 예! 고마워, 바트. –

3

PHP's built-in Tokenizer 기능을 사용하거나 Zend Framework의 Zend_CodeGenerator을 사용하는 것이 더 안전한 방법이라고 생각합니다. 이것들은 또한 코드를 더 읽기 쉽게 유지합니다.

이것은 regexp를 사용하여 소스 코드를 구문 분석하려는 경우 자체 토큰 세트를 유지해야하지만 기본 제공 솔루션이 있기 때문입니다.