Замените php-функции комментариями, используя str_replace() и 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() для создания нового каталога".
Есть ли способ в регулярном выражении, чтобы исключить совпадения в комментариях?
Я просто хочу заменить функции, которые находятся за пределами области комментариев.
2 ответа
Это можно сделать для всех видов комментариев php, используя регулярное выражение, подобное этому:
~^(?:(?!(?://|#|/\*)).)*\K((?:mkdir|fopen)\s*\()~m
Легенда:
^
Начало линии (благодаря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);
?>
ВНИМАНИЕ:
- это не обрабатывает (удаленный) регистр индикатора комментария внутри строки, как хеш внутри строки
"...#..."
или же"...//..."
или же".../*..."
- Не обрабатывает правильно многострочные комментарии
/* ... */
когда функция не встроена. (/*...mkdir()...*/
работает как положеноmkdir
пропускается в то время как/*...\n...mkdir()...*/
(Обратите внимание\n
)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);