preg_replace shim с поддержкой eval
Это очень нецелесообразно. Но если вы не программист или действительно предпочитаете ужасный код, вы можете использовать заменяющую preg_replace
функцию, чтобы ваш /e
флаг временно работал .
function preg_replace_eval($pattern, $replacement, $subject, $limit=-1) {
$pattern = preg_replace('/(\W[a-df-z]*)e([a-df-z]*)$/i', '$1$2', $pattern);
if (preg_match('/\(\.[+*]/', $pattern)) {
trigger_error("preg_replace_eval(): regex contains (.*) or (.+) placeholders, which easily causes security issues for unconstrained/user input in the replacement expression. Transform your code to use preg_replace_callback() with a sane replacement callback!");
}
return preg_replace_callback(
$pattern,
function ($matches) use ($replacement) {
$repl = preg_replace_callback(
'/(?<!\\\\)(?:[$]|\\\\)(\d+)/',
function ($m) use ($matches) {
if (!isset($matches[$m[1]])) { trigger_error("No capture group for '$m[0]' eval placeholder"); }
return addcslashes($matches[$m[1]], '\"\'\`\$\\\0');
},
$replacement
);
return eval("return $repl;");
},
$subject,
$limit
);
}
В сущности, вы просто включить эту функцию в вашем коде, и редактировать preg_replace
в preg_replace_eval
там , где/e
был использован флаг.
Плюсы и минусы :
- На самом деле только что протестирован с несколькими образцами из Stack Overflow.
- Поддерживает только простые случаи (вызовы функций, а не поиск переменных).
- Содержит еще несколько ограничений и рекомендательных уведомлений.
- Будет приводить к вывихнутым и менее понятным ошибкам для ошибок выражения.
- Тем не менее, это временное решение, которое можно использовать, и оно не усложняет правильный переход на
preg_replace_callback
.
- И комментарий к лицензии предназначен только для того, чтобы удержать людей от чрезмерного использования или распространения этого слишком далеко.
Генератор кода замены
Теперь это несколько избыточно. Но может помочь тем пользователям, которым все еще сложно вручную реструктурировать свой код в формат preg_replace_callback
. Хотя это фактически требует больше времени, у генератора кода меньше проблем с /e
преобразованием строки замены в выражение. Это ничем не примечательное преобразование, но его, вероятно, достаточно для наиболее распространенных примеров.
Чтобы использовать эту функцию, отредактируйте любой прерванный preg_replace
вызов preg_replace_eval_replacement
и запустите его один раз . Это распечатает соответствующий preg_replace_callback
блок, который будет использоваться вместо него.
function preg_replace_eval_replacement($pattern, $replacement, $subjectvar="IGNORED") {
$pattern = preg_replace('/(\W[a-df-z]*)e([a-df-z]*)$/i', '$1$2', $pattern);
$replacement = preg_replace_callback('/[\'\"]?(?<!\\\\)(?:[$]|\\\\)(\d+)[\'\"]?/', function ($m) { return "\$m[{$m[1]}]"; }, $replacement);
$ve = "var_export";
$bt = debug_backtrace(0, 1)[0];
print "<pre><code>
#----------------------------------------------------
# replace preg_*() call in '$bt[file]' line $bt[line] with:
#----------------------------------------------------
\$OUTPUT_VAR = preg_replace_callback(
{$ve($pattern, TRUE)},
function (\$m) {
return {$replacement};
},
\$YOUR_INPUT_VARIABLE_GOES_HERE
)
#----------------------------------------------------
</code></pre>\n";
}
Помните, что простое копирование и вставка - это не программирование. Вам придется адаптировать сгенерированный код обратно к вашим фактическим именам переменных ввода / вывода или контексту использования.
- В частности,
$OUTPUT =
присвоение должно быть выполнено, если предыдущий preg_replace
вызов использовался в if
.
- Однако лучше всего сохранить временные переменные или многострочную структуру блока кода.
И выражение замены может потребовать дополнительных улучшений читабельности или переделки.
- Например,
stripslashes()
буквальные выражения часто становятся избыточными.
- Для поиска с переменной областью видимости требуется
use
илиglobal
ссылка для / в обратном вызове.
- Ссылки
"-$1-$2"
захвата, заключенные неравномерно в кавычки, будут синтаксически нарушены простым преобразованием в "-$m[1]-$m[2]
.
Вывод кода - это просто отправная точка. И да, это было бы более полезно в качестве онлайн-инструмента. Такой подход к переписыванию кода (редактирование, запуск, редактирование, редактирование) в некоторой степени непрактичен. Тем не менее, он может быть более доступным для тех, кто привык к программированию, ориентированному на задачи (больше шагов, больше открытий). Таким образом, эта альтернатива может ограничить еще несколько повторяющихся вопросов.