function preg_replace_safe($search, $replace, $subject, $evaluator = NULL) { if (is_null($evaluator)) { $evaluator = function($code) { return eval($code); }; } if (is_array($subject)) { return array_map(function($subject) use ($search, $replace) { return preg_replace_safe($search, $replace, $subject); }, $subject); } else { if (is_array($search) && is_array($replace)) { $replacements = array_map(function($a, $b) { return [$a, $b]; }, $search, $replace); } else if(is_array($search)) { $replacements = array_map(function($a) use($replace) { return [$a, $replace]; }, $search); } else { $replacements = [[$search, $replace]]; } foreach ($replacements as $replacement) { list ($s, $r) = $replacement; if (is_callable($r)) { $subject = preg_replace_callback($s, $r, $subject); } else { $stripped = preg_replace("/^(.)(.*\\1[a-z]*)e([a-z]*)$/si", "$1$2$3", $s); if ($stripped != $s) { $subject = preg_replace_callback($stripped, function($matches) use ($r, $evaluator) { $code = preg_replace_callback("/\\$(?|\{(\\d+)\}|(\\d+))/", function($m) use ($matches) { return addslashes($matches[(int) $m[1]]); }, $r); return $evaluator("return " . $code . ";"); }, $subject); } else { $subject = preg_replace($s, $r, $subject); } } } return $subject; } }