Мне нужна помощь в фильтрации плохих слов в C? - PullRequest
0 голосов
/ 11 октября 2019

Как видите, я пытаюсь отфильтровать разные плохие слова. У меня есть код для этого. Я использую C, и это также для приложения GTK.

char LowerEnteredUsername[EnteredUsernameLen];
for(unsigned int i = 0; i < EnteredUsernameLen; i++) {
    LowerEnteredUsername[i] = tolower(EnteredUsername[i]);
}
LowerEnteredUsername[EnteredUsernameLen+1] = '\0';
if (strstr(LowerEnteredUsername, (char[]){LetterF, LetterU, LetterC, LetterK})||strstr(LowerEnteredUsername, (char[]){LetterF, LetterC, LetterU, LetterK})) {
    gtk_message_dialog_set_markup((GtkMessageDialog*)Dialog, "This username seems to be innapropriate.");
    UsernameErr = 1;
}

Моя проблема в том, что он будет фильтровать только последнее плохое слово, указанное в операторе if. В этом примере «fcuk». Если я введу «fuck», код передаст его как чистый. Как я могу это исправить?

Ответы [ 2 ]

0 голосов
/ 11 октября 2019
(char[]){LetterF, LetterU, LetterC, LetterK}
(char[]){LetterF, LetterC, LetterU, LetterK}

Вы забыли завершить свои строки с помощью '\0'. Мне кажется, что этот подход не очень эффективен для предотвращения попадания ~ плохих слов в исходный код, поэтому я бы действительно предложил просто написать обычные строковые литералы:

if (strstr(LowerEnteredUsername, "fuck") || strstr(LowerEnteredUsername, "fcuk")) {

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

"f" "u" "c" "k"

или

#define LOWER_F "f"
#define LOWER_U "u"
#define LOWER_C "c"
#define LOWER_K "k"

и

LOWER_F LOWER_U LOWER_C LOWER_K
0 голосов
/ 11 октября 2019

Обработка текста на человеческом языке в C болезненна, потому что концепция строк в C (например, char* / char[] и wchar_t* / wchar_t[]) очень низкоуровнева и недостаточно выразительна, чтобы легко представляет текст Unicode, не говоря уже о том, чтобы находить границы слов в тексте и сопоставлять слова в известном словаре (также учитывайте такие вещи, как перегибы, склонения, множественное число, использование диакритических знаков, чтобы избежать наивного сопоставления строк).

Например, ваша программа должна была бы обрабатывать знаменитые Семь грязных слов Джорджа Карлина цитата:

https://www.youtube.com/watch?v=vbZhpf3sQxQ

Кто-то очень заинтересовался этими словами. Они продолжали ссылаться на них: они называли их плохими, грязными, грязными, грязными, мерзкими, вульгарными, грубыми, с плохим вкусом, непристойными, уличными разговорами, разговорами о водосточных трубах, языком в раздевалке, разговорами о казармах, непристойными, озорными, дерзкими, грубыми,Грубый, грубый, храбрый, похотливый, непристойный, оскверненный, непристойный, синий, не цветовой, рискованный, наводящий на размышления, ругающийся, ругающийся, ругаясь ... и все, о чем я мог думать, было: дерьмо, моча, ебать, пизда, хуесос,ублюдок и сиськи!

Это можно немного изменить, чтобы избежать наивного фильтра, например:

Кто-то очень заинтересовался этими словами. Они продолжали ссылаться на них: они называли их плохими, грязными, грязными, грязными, мерзкими, вульгарными, грубыми, с плохим вкусом, непристойными, уличными разговорами, разговорами о водосточных трубах, языком в раздевалке, разговорами о казармах, непристойными, озорными, дерзкими, грубыми,Грубый, грубый, храбрый, похотливый, непристойный, оскверненный, непристойный, синий, не в цвете, рискованный, наводящий на размышления, ругань, ругань, ругань ... и все, что я мог придумать, было: дерьмо, пис, фук, не, минет, ублюдок и все такое!

Выше некоторые слова имеют простую замену, например s на $, в другие добавлены диакритические знаки, например u к ú,а некоторые - просто омонимы ), однако некоторые другие слова в приведенном выше выглядят одинаково , но на самом деле содержат омографов или "невидимых" символов, таких как ноль-юникодwidth-space, чтобы они избегали наивных систем сопоставления текста.

Короче говоря: избегайте делать это в C., если необходимо, тогда используйте надежную и полнофункциональную библиотеку обработки Unicode (т.е. не используйтеC StaСтроковые функции библиотеки ndard, такие как strstr, strtok, strlen и т. д.).

Вот как я бы это сделал:

  1. Чтение во входных данных двоичного двоичного объекта, содержащегоТекст Unicode (предположительно UTF-8).
  2. Используйте библиотеку Unicode для:
    1. Нормализации закодированных текстовых данных Unicode (см. https://en.wikipedia.org/wiki/Unicode_equivalence)
    2. Идентификационное словограницы (при условии, что мы имеем дело с языками европейского стиля, в которых используются предложения, состоящие из слов).
    3. Используйте лингвистическую библиотеку и базу данных (только на английском языке полно специальных случаев), чтобы нормализовать каждое слово к некоторому единственному каноническомуform.
    4. Затем ищите каждую морфему в нечувствительном к регистру хеш-наборе известных "плохих слов".

Теперь есть несколько ярлыков, которые выможет принимать:

  • Вы можете использовать регулярные выражения для определения границ слов.
  • Существуют библиотеки регулярных выражений с поддержкой Unicode для C, например PCRE2: http://www.pcre.org/current/doc/html/pcre2unicode.html
  • Вы можете пропустить нормализацию каждого слова / declensions, если вы довольны тем, что перечислите их в своем списке «плохих слов».

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

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...