【问题标题】:Why does my profanity filter not work?为什么我的脏话过滤器不起作用?
【发布时间】:2011-05-06 17:55:55
【问题描述】:
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);
}

有没有更好的方法来做到这一点?

我的过滤器没有捕捉到它需要的东西。

【问题讨论】:

  • 您发布的代码有效吗?在我看来没问题。我对“未捕获”位感到困惑。
  • 在这种情况下 text.trim().toLowerCase() 返回什么?
  • @duffymo:我认为 Donut 下面的评论解决了这个问题。我需要一些方法来检查text 中是否存在cursewords 条目anywhere
  • 作为记录,您可能需要查看 Jeff 的这篇关于过滤器的文章 codinghorror.com/blog/2008/10/…
  • 感谢你用你那可怕的脏话列表度过我的一天 :-)

标签: java list string


【解决方案1】:

您的过滤器目前仅在textcursewords 中的条目之一相同(根本没有其他字符)时才有效。要修复它,您需要改为遍历 cursewords 中的项目并检查 text 是否包含它。

这是一个简单的例子(使用enhanced for loop):

// 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);
    }
}

尽管正如其他人所提到的,使用正则表达式来解释诅咒的变化并避免使用clbuttic mistakes 可能会更好。

【讨论】:

  • 我认为这就是问题所在。我需要某种方法来检查text 中任何地方是否存在cursewords 条目。
  • 更新了一个简单的例子。
  • 这似乎相当低效 - 如果文本是一本书的全部内容怎么办?这意味着您将在每次迭代中检查一个巨大的字符串。为什么不将文本拆分为单个单词,然后将每个单词与一组诅咒词进行比较?
【解决方案2】:

您的代码在这一行有错误:

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

) 将您的if 语句括起来,如下所示:

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

结果,提供的代码现在可以工作了:

找到诅咒:天哪

【讨论】:

    【解决方案3】:

    List.contains() 将寻找完全匹配。

    也许你需要这样做:

    for(String curseword:cursewords) {
        //wrong
        //if(curseword.contains(text.trim().toLowerCase())) {
        if(text.trim().toLowerCase().contains(curseword)) {
            ...
        }
    }
    

    【讨论】:

    • 你有这个倒退。应该是:if (text.trim().toLowerCase().contains(curseword) { ... },否则原始代码会起作用,因为您假设文本已经拆分为单个单词。
    • -1,完全匹配。 “ Golly ”被修剪为“Golly”并简化为小写“golly”; “golly”也是添加到列表中的最后一个词cursewords
    • 你说得对,我没听懂。我假设文本会是“哦,天哪”的效果。
    【解决方案4】:

    RegEx 过滤器是查找诅咒作品的更好方法,因为 f*k 或 a*muncher 可能有多个不同的中间部分。查看Pattern 类和Mattcher 类,获取有关如何编写诅咒词过滤器的提示。

    【讨论】:

    • 这会抓住 fork 和 applemuncher
    【解决方案5】:

    这种方法与正则表达式不同。它假定您已经将您的短语解析为单个单词。

    【讨论】:

      【解决方案6】:

      其他人已经指出了您代码中的错误。然而,一个普遍的改进是使用词干分析器对文本进行预处理,然后将输出与一组更易于管理的“根”诅咒词进行比较。例如,“翻转”的词干将是“翻转”。然后,不是每次都针对每个诅咒词检查整个文本,而是遍历文本中的每个预处理词并检查它是否等于任何一个词干诅咒词。

      其他更明显的预处理措施是删除所有标点符号并使所有文本小写。

      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");
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2023-03-13
        • 1970-01-01
        • 1970-01-01
        • 2017-02-10
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多