Замените 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 закомментировано).

У меня нет умного ответа, следующее - просто способ, который не очень хорош, но может решить.

  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);
Другие вопросы по тегам