Фильтр ненормативной лексики с использованием регулярного выражения (список из 100 слов)

Как правильно удалить ненормативную лексику из заданной строки:
1) У меня есть список из 100 слов, которые нужно искать в массиве строк. 2) Как правильно обрабатывать неполные слова? Как большинство людей справляются с этим? Например, слово масса. Тогда иногда неполное слово также плохо - предположим, что foobar - чрезвычайно ненормативное слово, я могу запретить foobar и foobar* и *foobar.

Итак, вы помещаете все слова в одно выражение или выполняете цикл по списку?

Как правильно с этим справиться? Я использую Groovy/Grails, но приветствуются любые примеры современных языков.


person BuddyJoe    schedule 29.11.2011    source источник
comment
Проверьте эту ссылку: stackoverflow.com/questions/273516/   -  person Chris Laplante    schedule 30.11.2011
comment
Обратите внимание на проблему Сканторпа: en.wikipedia.org/wiki/Scunthorpe_problem   -  person rossum    schedule 30.11.2011


Ответы (3)


Это довольно сложная проблема для решения, и вам нужно определить, будут ли работать для вас регулярные выражения и как вы справляетесь с встраиванием (когда вы добавляете словарное слово к ненормативной лексике, такой как frackface, за исключением настоящего F-слова).

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

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

  • Пункт списка
  • h e l l o
  • h.e.l.l.o
  • h_e_l_l_o
  • |-|привет
  • привет
  • «привет» (эта фраза может не содержать ненормативной лексики, но вместе они являются ненормативной лексикой)

Вам также необходимо обработать пограничные случаи, когда два или более слов из словаря (из белого списка) содержат ненормативную лексику рядом друг с другом. Некоторые примеры, которые содержат s-слово:

  • разбей это
  • ssh это тихое время

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

Мы потратили последние 3 года на совершенствование фильтра, используемого CleanSpeak, чтобы гарантировать, что он обрабатывает все эти случаи, и мы продолжаем настраивать это и сделать его лучше. Мы также потратили 8 месяцев на совершенствование нашей системы для повышения производительности, и она может обрабатывать около 5000 сообщений в секунду. Нельзя сказать, что вы не можете создать что-то полезное, но будьте готовы справиться с множеством проблем, которые могут возникнуть, а также создать систему, не использующую регулярные выражения.

person voidmain    schedule 01.12.2011

  1. Объединить каждое слово в список слов - (foobar|foobaz|...)
  2. Затем поставьте охрану по обеим сторонам группировки от посторонних персонажей.

    [^!@#$%^&*]*(foobar|foobaz|foofii)[^!@#$%^&*]*

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

Что касается производительности, объединение этого в одно большое регулярное выражение, вероятно, будет самым быстрым (хотя я не эксперт). Алгоритм регулярного выражения довольно эффективен при поиске и обработке условий ветвления. По сути, это должно быть лучше, чем O(mn) (где m — количество слов, а n — размер текста, который вы ищете)

person kelloti    schedule 30.11.2011

Я работал над этим регулярным выражением ранее, и он должен соответствовать пробелам и другим символам между ними:

/^f(\s|.{1,2})?o?(\s|.{1,2})?o.*$/gi

Проверяет:

фу

f.o.o

f oo

фубар

person Hisoka    schedule 27.05.2021