我想禁用编辑器的一些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()函数来创建一个新的目录。"
正则表达式中有没有任何方法可以排除注释中的匹配?
我只想替换评论区之外的函数。
我没有一个聪明的答案,以下只是一个不好但可以解决的方法。
- 将"或"中的所有特殊字符串替换为另一个特殊字符串,如
"~~^^~~"
- 做上一次替换
- 将"~^^~~"更改为正常
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()...*/
(注意'n
)mkdir
被注释掉)