Как реализовать хороший фильтр ненормативной лексики? - PullRequest
194 голосов
/ 07 ноября 2008

Многим из нас приходится иметь дело с пользовательским вводом, поисковыми запросами и ситуациями, когда вводимый текст может содержать ненормативную лексику или нежелательный язык. Часто это нужно отфильтровать.

Где можно найти хороший список нецензурных слов на разных языках и диалектах?

Доступны ли API для источников, содержащих хорошие списки? Или, может быть, API, который просто говорит «да, это чисто» или «нет, это грязно» с некоторыми параметрами?

Какие есть хорошие методы для ловли людей, пытающихся обмануть систему, например, $$, azz или a55?

Бонусные баллы, если вы предлагаете решения для PHP. :)

Редактировать: Ответ на ответы, в которых говорится, просто избегайте программной проблемы:

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

Так что я действительно имею в виду способ выяснить, является ли грязный токен грязным или нет, а затем просто запретить его. Я бы не стал предотвращать такое чувство, как совершенно смешное упоминание о «длинношерстном жирафе». Вы ничего не можете сделать там. :)

Ответы [ 21 ]

4 голосов
/ 29 октября 2012

Я немного опоздал на вечеринку, но у меня есть решение, которое может сработать для тех, кто читает это. Это в javascript вместо php, но для этого есть веская причина.

Полное раскрытие, я написал этот плагин ...

В любом случае.

Подход, с которым я столкнулся, заключается в том, чтобы позволить пользователю «согласиться» на их фильтрацию ненормативной лексики. В основном ненормативная лексика будет разрешена по умолчанию, но если мои пользователи не хотят читать ее, они не должны. Это также помогает с проблемой «l33t sp3 @ k».

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

Вот демонстрационная страница
https://chaseflorell.github.io/jQuery.ProfanityFilter/demo/

<div id="foo">
    ass will fail but password will not
</div>

<script>
    // code:
    $('#foo').profanityFilter({
        customSwears: ['ass']
    });
</script>

результат

*** не удастся, но пароль не будет

2 голосов
/ 03 марта 2017

Я собрал 2200 плохих слов на 12 языках: en, ar, cs, da, de, eo, es, fa, fi, fr, hi, hu, it, ja, ko, nl, no, pl, pt, ru, sv, th, tlh, tr, zh.

Доступны опции MySQL dump, JSON, XML или CSV.

https://github.com/turalus/openDB

Я бы посоветовал вам выполнить этот SQL в вашей БД и проверять каждый раз, когда пользователь вводит что-то.

2 голосов
/ 16 августа 2011

Если у вас есть хорошая таблица MYSQL с некоторыми плохими словами, которые вы хотите отфильтровать (я начал с одной из ссылок в этой теме), вы можете сделать что-то вроде этого:

$errors = array();  //Initialize error array (I use this with all my PHP form validations)

$SCREENNAME = mysql_real_escape_string($_POST['SCREENNAME']); //Escape the input data to prevent SQL injection when you query the profanity table.

$ProfanityCheckString = strtoupper($SCREENNAME); //Make the input string uppercase (so that 'BaDwOrD' is the same as 'BADWORD').  All your values in the profanity table will need to be UPPERCASE for this to work.

$ProfanityCheckString = preg_replace('/[_-]/','',$ProfanityCheckString); //I allow alphanumeric, underscores, and dashes...nothing else (I control this with PHP form validation).  Pull out non-alphanumeric characters so 'B-A-D-W-O-R-D' shows up as 'BADWORD'.

$ProfanityCheckString = preg_replace('/1/','I',$ProfanityCheckString); //Replace common numeric representations of letters so '84DW0RD' shows up as 'BADWORD'.

$ProfanityCheckString = preg_replace('/3/','E',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/4/','A',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/5/','S',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/6/','G',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/7/','T',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/8/','B',$ProfanityCheckString);

$ProfanityCheckString = preg_replace('/0/','O',$ProfanityCheckString); //Replace ZERO's with O's (Capital letter o's).

$ProfanityCheckString = preg_replace('/Z/','S',$ProfanityCheckString); //Replace Z's with S's, another common substitution.  Make sure you replace Z's with S's in your profanity database for this to work properly.  Same with all the numbers too--having S3X7 in your database won't work, since this code would render that string as 'SEXY'.  The profanity table should have the "rendered" version of the bad words.

$CheckProfanity = mysql_query("SELECT * FROM DATABASE.TABLE p WHERE p.WORD = '".$ProfanityCheckString."'");
if(mysql_num_rows($CheckProfanity) > 0) {$errors[] = 'Please select another Screen Name.';} //Check your profanity table for the scrubbed input.  You could get real crazy using LIKE and wildcards, but I only want a simple profanity filter.

if (count($errors) > 0) {foreach($errors as $error) {$errorString .= "<span class='PHPError'>$error</span><br /><br />";} echo $errorString;} //Echo any PHP errors that come out of the validation, including any profanity flagging.


//You can also use these lines to troubleshoot.
//echo $ProfanityCheckString;
//echo "<br />";
//echo mysql_error();
//echo "<br />";

Я уверен, что есть более эффективный способ сделать все эти замены, но я не достаточно умен, чтобы понять это (и это, кажется, работает хорошо, хотя и неэффективно).

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

Я также был бы очень осторожен, если вы хотите использовать подстановочные знаки, поскольку иногда они могут вести себя более обременительно, чем вы предполагаете.

2 голосов
/ 24 февраля 2009

Я согласен с постом HanClinto выше в этой дискуссии. Я обычно использую регулярные выражения для совпадения строк входного текста. И это тщетное усилие, так как, как вы уже упоминали, вы должны явно учитывать все хитрые формы письма, популярные в сети, в вашем «заблокированном» списке.

В дополнение к этому, в то время как другие обсуждают этику цензуры, я должен согласиться с тем, что в Интернете необходима некоторая форма. Некоторым людям просто нравится публиковать вульгарность, потому что она может быть мгновенно оскорбительной для большого количества людей и не требует абсолютно никаких мыслей со стороны автора.

Спасибо за идеи.

Правила HanClinto!

2 голосов
/ 07 ноября 2008

Не. Это просто приводит к проблемам. Один из моих личных опытов с фильтрами ненормативной лексики - это время, когда меня выгнали / забанили на канале IRC за упоминание о том, что я «направлялся через мост на Хэнкок на пару часов» или что-то в этом роде.

1 голос
/ 07 ноября 2008

Честно говоря, я бы позволил им вывести слова "обмануть систему" и запретить их, а это только я. Но это также упрощает программирование.

Я бы применил фильтр регулярных выражений, например, так: /[\s]dooby (doo?)[\s]/i или это слово с префиксом для других, /[\s]doob(er|ed|est)[\s]/. Это предотвратит фильтрацию слов, таких как предопределенный, что вполне допустимо, но также потребует знания других вариантов и обновления фактического фильтра, если вы изучите новый. Очевидно, что это все примеры, но вам придется решить, как сделать это самостоятельно.

Я не собираюсь печатать все слова, которые я знаю, не тогда, когда я на самом деле не хочу их знать.

1 голос
/ 12 октября 2012

Я пришел к выводу, что для создания хорошего фильтра ненормативной лексики нам нужно 3 основных компонента, или, по крайней мере, это то, что я собираюсь сделать. Вот они:

  1. Фильтр: фоновый сервис, который проверяет черный список, словарь или что-то в этом роде.
  2. Не разрешать анонимный аккаунт
  3. Сообщить о нарушении

Бонус, это будет вознаграждение тем, кто вносит свой вклад с точными издевательствами над журналистами и наказывать нарушителя, например. приостановить их учетные записи.

1 голос
/ 30 сентября 2010

Я согласен с бесполезностью предмета, но если вам нужен фильтр, проверьте Самшит Нина :

Boxwood - это расширение PHP для быстрой замены нескольких слов в тексте. Он поддерживает регистрозависимое и регистрозависимое сопоставление. Требуется, чтобы текст, с которым он работает, был закодирован как UTF-8.

Также см. Этот блог для более подробной информации:

В Boxwood ваш список поисковых терминов может быть настолько длинным, насколько вам нужно - алгоритм поиска и замены не замедляется, добавляя больше слов в список слов для поиска. Он работает путем создания трех всех поисковых терминов, а затем сканирует текст вашего предмета только один раз, просматривая элементы этого дерева и сравнивая их с символами в вашем тексте. Он поддерживает US-ASCII и UTF-8, регистрозависимое или нечувствительное сопоставление и имеет некоторую логику проверки границ слов, ориентированную на английский.

0 голосов
/ 25 апреля 2019

Также поздно в игре, но проводил некоторые исследования и наткнулся здесь. Как уже упоминали другие, это почти почти невозможно, если бы это было автоматизировано, но если ваш дизайн / требование может включать в некоторых случаях (но не всегда) человеческие взаимодействия, чтобы проверить, является ли это нечестным или нет, вы можете рассмотреть ОД. https://docs.microsoft.com/en-us/azure/cognitive-services/content-moderator/text-moderation-api#profanity мой текущий выбор по нескольким причинам:

  • Поддерживает множество локализаций
  • Они продолжают обновлять базу данных, поэтому мне не нужно следить за последними сленгами или языками (проблема с обслуживанием)
  • Когда существует высокая вероятность (т. Е. 90% или более), вы можете просто прагматично это отрицать
  • Вы можете наблюдать за категорией, которая вызывает флаг, который может быть или не быть ненормативной лексикой, и может заставить кого-то просмотреть его, чтобы понять, что он профан или нет.

Для моих нужд это было / основано на общедоступной коммерческой службе (ОК, видеоигры), которую другие пользователи могут / будут видеть имя пользователя, но дизайн требует, чтобы он прошел через фильтр ненормативной лексики, чтобы отклонить оскорбительное имя пользователя. Грустная часть этого вопроса в том, что классическая проблема «clbuttic», скорее всего, возникнет, поскольку имена пользователей, как правило, состоят из одного слова (до N символов), иногда объединяющего несколько слов… Опять же, когнитивная служба Microsoft не будет помечать «Assist» как текст. HasProfanity = true, но может указывать высокую вероятность для одной из категорий.

Когда ОП запрашивает, как насчет "$$", вот результат, когда я пропустил его через фильтр: enter image description here, как вы можете видеть, он определил, что это не профан, но вероятность того, что это так, отмечается как рекомендации по рассмотрению (взаимодействие человека).

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

Кстати, цена / цена на эту услугу довольно низкая для моей цели (как часто меняется имя пользователя?), Но, опять же, для OP, возможно, дизайн требует более интенсивных запросов и, возможно, не идеален для оплаты / подписаться на ML-сервисы или не может иметь обзор / взаимодействие с человеком. Все зависит от дизайна ... Но если дизайн отвечает всем требованиям, возможно, это может быть решением OP.

Если интересно, я могу перечислить минусы в комментарии в будущем.

0 голосов
/ 21 июня 2015

Фильтры ненормативной лексики - плохая идея. Причина в том, что вы не можете поймать каждое нецензурное слово. Если вы попытаетесь, вы получите ложные срабатывания.

Ловля слов

Скажем так, вы хотите поймать F-Word. Легко, правда? Ну что ж, посмотрим.

Вы можете перебрать строку, чтобы найти "ебать". К сожалению, люди обманывают фильтры в наше время. Фильтр ненормативной лексики не улавливал "fuk".

Можно попытаться проверить наличие нескольких вариантов написания и вариантов слова, но это снизит производительность вашего кода. Чтобы поймать F-Word, вам нужно искать «fuc», «Fuc», «fuk», «Fuk», «F ***» и т. Д. И этот список можно продолжать и продолжать.

Как избежать невинности

Хорошо, а как насчет того, чтобы сделать его без учета регистра и игнорировать пробелы, чтобы он ловил "F u C k"? Это может звучать как хорошая идея, но кто-то может просто обойти фильтр ненормативной лексики с "F.U.C.K."

Вы игнорируете пунктуацию.

Теперь это реальная проблема, поскольку предложение типа " Ад о, там!" будет воспринимать как "ад" и "Wh зад вверх?" воспринимается как "задница"

И есть несколько слов, которые вы должны исключить из фильтра, такие как "Минусы синица ution", потому что в них есть "синица".

Люди могут также использовать замещающие слова, такие как «Frack». Вы тоже это блокируете? А как насчет «ручка» для «пенис»? Ваша программа не имеет искусственного интеллекта, чтобы знать, хороша ли строка или нет.

Не используйте ненормативную лексику. Их сложно развивать, и они так же медленны, как ползать.

...