Создание фильтра слов на PHP


Вы, без сомнения, знакомы с понятием словесного фильтра - функции, которая заменяет «нехорошие» слова звездочками. Есть много случаев, когда слово фильтр полезен. Фильтр ненормативной лексики может сохранить сайту репутацию «чистого», удалив ненормативную лексику, в то время как фильтр слов также может быть использован просто для удаления любых слов, которые не должны появляться в блоке текста (например, удаление спам-терминов или технических данных).

Хороший фильтр слов должен поддерживать регулярные выражения, которые позволяют вам определять различные формы слова, не печатая их все. Регулярное выражение / \ bass (es | hole?)? \ B / i будет соответствовать большинству экземпляров A-слова без генерации ложных срабатываний. Нет ничего более раздражающего, чем словесный фильтр, цензурирующий такие слова, как «классический» без видимой причины.

Простой фильтр слов

Самый простой из всех текстовых фильтров просто использует функцию str_replace () для замены каждого вхождения слова. Вы можете создать простую функцию следующим образом:

function wordFilter($text)
{
    $filtered_text = $text;
    $filtered_text = str_replace('ass', '***', $filtered_text);
    $filtered_text = str_replace('shit', '****', $filtered_text);
    // ... и так далее
    return $filtered_text;
}
Однако этот метод далек от совершенства. Как видите, этот код:

echo wordFilter('My ass Ass asshole classroom shit shithead');
будет выводить:

My *** Ass ***hole cl***room **** ****head
Поговорим о ложных срабатываниях! Этот код не смог отфильтровать форму «непослушного» слова, которое оказалось заглавным, а также уловило совершенно невинное слово (классная комната).

Регулярные выражения

Регулярные выражения значительно облегчают сопоставление различных форм одного слова и могут использоваться для ограничения поиска только целыми словами (чтобы избежать ложных срабатываний). Базовый фильтр, использующий регулярные выражения, может быть реализован следующим образом:

function wordFilter($text)
{
    $filter_terms = array('/\bass(es|holes?)?\b/i', '/\bshit(e|ted|ting|ty|head)\b/i');
    $filtered_text = preg_replace($filter_terms, '***', $filtered_text);
    return $filtered_text;
}
Обратите внимание, что теперь можно ограничить фильтр только такими словами, как «ass», «asses», но игнорировать такие слова, как «classroom». Модификатор \ b указывает поиску на совпадение только с целыми словами, а / i - игнорирует регистр. Передав в фильтр ту же строку текста, мы получим:

My *** *** *** classroom *** ***
Это работает ... но далеко не идеально. Хотя этот фильтр успешно перехватывает любые слова из черного списка (и их варианты), для которых он запрограммирован, он заменяет каждый термин фиксированным числом ***. Это не подходит для большинства приложений.

Готовый фильтр

Как создать фильтр, который не только разрешает регулярные выражения, но также заменяет каждый отфильтрованный термин требуемым количеством звездочек?

function wordFilter($text)
{
    $filter_terms = array('\bass(es|holes?)?\b', '\bshit(e|ted|ting|ty|head)\b');
    $filtered_text = $text;
    foreach($filter_terms as $word)
    {
        $match_count = preg_match_all('/' . $word . '/i', $text, $matches);
        for($i = 0; $i < $match_count; $i++)
            {
                $bwstr = trim($matches[0][$i]);
                $filtered_text = preg_replace('/\b' . $bwstr . '\b/', str_repeat("*", strlen($bwstr)), $filtered_text);
            }
    }
    return $filtered_text;
}
Опять же, передавая в этот фильтр ту же строку текста, мы получаем:

My *** *** ******* classroom **** ********
Вы можете легко добавлять слова в массив $ filter_terms; обратите внимание, что начало / и конечный / i автоматически включаются в цикл, устраняя необходимость каждый раз вводить их. Вы также можете добавить «жадные» совпадения; просто удалите \ b с обоих концов слова, и фильтр поймает все, что содержит в себе это слово. Хорошей идеей было бы загрузить все термины в массив из внешнего файла.

В зависимости от желаемого уровня «чистоты», вы можете изменить способ отображения отфильтрованных терминов. Например, вы можете сохранить первые и последние буквы слова, если хотите, чтобы пользователь мог угадать исходный термин; Вы также можете добавить встроенный HTML, который отображает исходное слово в виде всплывающей подсказки.

Если вам требуется сделать что-то подобное на вашем сайте, то пишите мне.

Автор этого материала - я - Пахолков Юрий. Я оказываю услуги по написанию программ на языках Java, C++, C# (а также консультирую по ним) и созданию сайтов. Работаю с сайтами на CMS OpenCart, WordPress, ModX и самописными. Кроме этого, работаю напрямую с JavaScript, PHP, CSS, HTML - то есть могу доработать ваш сайт или помочь с веб-программированием. Пишите сюда.

тегизаметки, php, сайтостроение, фильтрация




Отправляя сообщение я подтверждаю, что ознакомлен и согласен с политикой конфиденциальности данного сайта.




Генератор детективного романа на Java
Урок 11. Директивы v-text, v-once, v-pre и v-html Vue 3
Протокол HTTP