Methods for removing RegEx from code

With regular expressions, I am trying to remove all methods / functions from the following code. There is only one way out of the "global scale". However, I can’t make it match all the internal contents of the method.

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

The current regular expression that I have is: (?:(public|protected|private|static)\s+)?function\s+\w+\(.*?\)\s+{.*?} However, it will not select a method with brackets inside, e.g. function user() .

If someone can point me in the right direction.

+4
source share
2 answers

You cannot do it right with regex. You need to write a parser that can correctly parse comments, string literals and nested brackets.

Regex cannot handle these cases:

 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

Here is a small demonstration of how to use the tokenizer function mentioned by 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 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 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 = ''; } } } } 

which will print:

 <?php $mother = new Mother("this function isNotAFunction($x=0) {} foo bar"); class Hello { $foo = 666; private $bar; } /* comment to preserve function noFunction(){} */ $mother->global(); ?> 

which is the original source, only without functions.

+6
source

I believe that using the built-in Tokenizer or Zend_CodeGenerator function from Zend Framework is a more secure way. They will also keep your code more readable.

This is simply because if you want to use regexp for source code analysis, you must save your own tokens, but there is a built-in solution.

+3
source

Source: https://habr.com/ru/post/1300555/


All Articles