使用str_Replace()和regex将php函数替换为注释


Replace php functions with comment using str_replace() and regex

我想禁用编辑器的一些php函数。如果用户发布了带有任何禁用函数的代码,那么preg_replace会将其转换为注释。

例如,如果fopen()在代码中的任何位置(不包括注释区)都可以找到,那么

更换

 fopen();

带有

 #fopen();

这是我迄今为止的

  $code='#you can use the mkdir() function to make a new dir.
 mkdir("love");
 echo "Hello world";
 fopen("home.php");'
 echo preg_replace("/(mkdir|fopen'(.*'))/i","#$1",$code);

它从两个方面取代了mkdir(),也从评论"#你可以使用mkdir()函数来创建一个新的目录。"

正则表达式中有没有任何方法可以排除注释中的匹配?

我只想替换评论区之外的函数。

我没有一个聪明的答案,以下只是一个不好但可以解决的方法。

  1. 将"或"中的所有特殊字符串替换为另一个特殊字符串,如"~~^^~~"
  2. 做上一次替换
  3. 将"~^^~~"更改为正常

PS:如果你有一个以上的功能,你可以使用"~~^^~~1","~~^^~~2"

这是代码:

$str = '"asdfasmkdir()sdljsdlffopen()sdfsd";fopen()';
$regix = '/"(.*?)mkdir(.*?)"/';
$changeArr = array(
    'mkdir' => '~~__~~1',
    'fopen' => '~~__~~2',
);
$newStr = $str;
//first step
foreach($changeArr as $k=>$v){
    $regix = '/(".*?)'.$k.'(.*?")/';
    $newStr = preg_replace($regix,'$1'.$v.'$2',$newStr);
}
var_dump($newStr);
//second step
//this is your code,by using $new Str
//third step
foreach($changeArr as $k=>$v){
    $regix = '/(".*?)'.$v.'(.*?")/';
    $newStr = preg_replace($regix,'$1'.$k.'$2',$newStr);
}
var_dump($newStr);

这可以使用如下正则表达式对所有类型的php注释执行:

~^(?:(?!(?://|#|/'*)).)*'K((?:mkdir|fopen)'s*'()~m

Legenda

  • ^行的起点(由于末尾有m多行修饰符)
  • (?:(?!(?://|#|/'*)).)*是一种多重调和贪婪位置检查。验证行中的文本,直到它不包含#///*
  • 'K重置正则表达式引擎此时选择的文本(丢弃上面表达式验证的所有文本)
  • ((?:mkdir|fopen)'s*'()从2个函数中选择一个,后面跟着零个或多个空格(或制表符)和一个开圆括号

试试这个在线演示。

更新

添加了运行演示的工作代码片段

<?php
$code = <<<CODE
#you can use the mkdir() function to make a new dir.
mkdir("love");
echo "Hello world";
fopen("home.php");
//mkdir()
/* fopen() */
CODE;
$re = "~^(?:(?!(?://|#|/'*)).)*'K((?:mkdir|fopen)'s*'()~m";
echo preg_replace($re,"#$1",$code);
?>

CAVEAT

  • 这不处理字符串中注释指示符的(远程)情况,就像字符串"...#...""...//..."".../*..."中的哈希一样
  • 当函数未内联时,无法正确处理多行注释/* ... */。(/*...mkdir()...*/按预期工作mkdir被跳过,而/*...'n...mkdir()...*/(注意'nmkdir被注释掉)