Почему мой фильтр ненормативной лексики не работает? - PullRequest
2 голосов
/ 08 ноября 2010
List<String> cursewords = new ArrayList<String>();
cursewords.add("darn it");
cursewords.add("gosh");
cursewords.add("gee whiz");
cursewords.add("golly");

String text = " Golly ";

if (cursewords.contains(text.trim().toLowerCase())  {
    System.out.println("found curse:" + text);
}

Есть ли лучший способ сделать это?

Мой фильтр не перехватывает то, что ему нужно.

Ответы [ 6 ]

4 голосов
/ 08 ноября 2010

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

Вот простой пример (используется расширенный for цикл ):

// Convert the string to lowercase here, instead of within the loop
string lowerCaseText = text.toLowerCase();

for (String curse : cursewords) {
    if (lowerCaseText.contains(curse)) {
       System.out.println("found curse:" + curse);
    }
}

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

1 голос
/ 08 ноября 2010

В вашем коде произошла ошибка в этой строке:

if (cursewords.contains(text.trim().toLowerCase())  {

Вложите if заявление с ), например:

if (cursewords.contains(text.trim().toLowerCase()))  {

Результат , указанный код теперь работает:

найдено проклятие: Golly

1 голос
/ 08 ноября 2010

List.contains () будет искать точное совпадение.

Может быть, вам нужно сделать это:

for(String curseword:cursewords) {
    //wrong
    //if(curseword.contains(text.trim().toLowerCase())) {
    if(text.trim().toLowerCase().contains(curseword)) {
        ...
    }
}
0 голосов
/ 08 ноября 2010

Другие уже указали на ошибку в вашем коде. Тем не менее, одним общим улучшением было бы использование стеммера для предварительной обработки текста, а затем сравнение выходных данных с более управляемым набором "корневых" ругательств. Например, основа "щелчка" была бы "щелчком". Затем, вместо того, чтобы каждый раз проверять весь текст на предмет каждого проклятого слова, перебирайте каждое предварительно обработанное слово в тексте и проверяйте, соответствует ли оно любому из ваших проклятых слов с основанием.

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

Set<String> stemmedCurseWords = new HashSet<String>();
stemmedCurseWords.add("flip");
stemmedCurseWords.add("gosh");

String text = "I was flipping late for work again."
boolean foundCurseWord = false;

String[] stemmedText = preprocess(text);
for (String word : stemmedText) {
  if (stemmedCurseWords.contains(word)) {
    foundCurseWord = true;
    break;
  }
}

if (foundCurseWord) {
  System.err.println("Bad manners");
}
0 голосов
/ 08 ноября 2010

Этот подход отличается от регулярного выражения. Предполагается, что вы уже разобрали свою фразу на отдельные слова.

0 голосов
/ 08 ноября 2010

Фильтры RegEx являются лучшим способом поиска проклятий, поскольку f * k или * может иметь несколько разных средних частей.Посмотрите на Pattern class и Mattcher class для подсказок о том, как написать фильтр проклятия.

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