У меня есть текст, который нужно отфильтровать список плохих слов, например:
$bad_words = array( 'word1' => 'gosh', 'word2' => 'darn', );
Я могу зациклиться на них и заменить один за раз, но это медленно? Есть ли способ лучше?
Да, есть. Используйте preg_replace_callback()
:
<?php header('Content-Type: text/plain'); $text = 'word1 some more words. word2 and some more words'; $text = preg_replace_callback('!\w+!', 'filter_bad_words', $text); echo $text; $bad_words = array( 'word1' => 'gosh', 'word2' => 'darn', ); function filter_bad_words($matches) { global $bad_words; $replace = $bad_words[$matches[0]]; return isset($replace) ? $replace : $matches[0]; } ?>
Это простой фильтр, но он имеет множество ограничений. Подобно этому, это не остановит вариации написания, использование пробелов или других неглавных символов между буквами, замену букв цифрами и т. Д. Но насколько изощренны вы хотите, чтобы это было в основном.
Я понимаю, что это 7 лет, но более новые версии php, похоже, генерируют исключение, если тестируемое слово не находится в массиве $bad_words
. Чтобы исправить это, я изменил последние две строки filter_bad_words()
следующим образом:
$replace = array_key_exists($matches[0], $bad_words) ? $bad_words[$matches[0]] : false; return $replace ?: $matches[0];
str_ireplace () может принимать массив как для аргументов поиска, так и для замены. Вы можете использовать его с существующим массивом следующим образом:
$unfiltered_string = "gosh and darn are bad words"; $filtered_string = str_ireplace(array_vals($bad_words), array_keys($bad_words), $unfiltered_string); // $filtered string now contains: "word1 and word2 are bad words"
Вот так:
function clean($array, $str) { $words = array_keys($array); $replacements = array_values($array); return preg_replace($words, $replacements, $str); }