【问题标题】:Filter words from string从字符串中过滤单词
【发布时间】:2012-06-18 02:03:48
【问题描述】:

我想过滤一个字符串。

基本上当有人键入消息时,我希望过滤掉某些单词,如下所示:

用户类型: hey guys lol omg -omg mkdj*Omg*ndid

我希望过滤器运行并且:

输出: hey guys lol - mkdjndid

我需要从包含多个要过滤掉的单词的ArrayList 加载过滤后的单词。现在我正在做if(message.contains(omg)),但如果有人键入 zomg 或 -omg 或类似的,那将不起作用。

【问题讨论】:

  • 在 Google 上搜索“正则表达式”,然后搜索“clbuttic”,以帮助了解您尝试尝试的难度。
  • 难吗?使用循环和审查词列表并不难......
  • @Thihara - 因此 clbuttic 参考......它不像你想象的那么容易。如果阻止特定的字符序列如此容易,那么跨站点脚本就不会成为问题。
  • 是的,我意识到,但完全按照他的意愿去做并不难......

标签: java string filter arraylist


【解决方案1】:

将 replaceAll 与从坏词构建的正则表达式一起使用:

message = message.replaceAll("(?i)\\b[^\\w -]*" + badWord + "[^\\w -]*\\b", "");

这通过了您的测试用例:

public static void main( String[] args ) {
    List<String> badWords = Arrays.asList( "omg", "black", "white" );
    String message = "hey guys lol omg -omg mkdj*Omg*ndid";
    for ( String badWord : badWords ) {
        message = message.replaceAll("(?i)\\b[^\\w -]*" + badWord + "[^\\w -]*\\b", "");
    }
    System.out.println( message );
}

【讨论】:

    【解决方案2】:

    尝试:

    input.replaceAll("(\\*?)[oO][mM][gG](\\*?)", "").split(" ")
    

    【讨论】:

    • 是的,但我可以将它与数组列表一起使用吗?
    • 对结果使用split() 方法。
    • 当然可以,StringUtils.join(list, " ").replaceAll(...).split(" ");
    【解决方案3】:

    Dave 已经给你答案了,但我会在这里强调声明。如果您使用一个简单的 for 循环来实现您的算法,该循环只是替换过滤词的出现,您将面临一个问题。例如,如果您过滤单词“classic”中的单词 ass 并将其替换为“butt”,则结果单词将是“clbuttic”,这没有任何意义。因此,我建议使用一个单词列表,例如存储在 Linux 中 /usr/share/dict/ 目录下的单词列表,以检查该单词是否有效或需要过滤。 我不太明白你想做什么。

    【讨论】:

      【解决方案4】:

      我遇到了同样的问题并通过以下方式解决了它:

      1) 有一个谷歌电子表格,其中包含我要过滤掉的所有字词

      2) 使用 loadConfigs 方法直接将 google 电子表格下载到我的代码中(见下文)

      3) 将所有 l33tsp33k 字符替换为各自的字母

      4) 替换句子中除字母以外的所有特殊字符

      5) 运行一个算法,有效地检查字符串中所有可能的单词组合与列表,注意这部分是关键 - 你不想每次都循环遍历整个列表来查看你的单词是否是在列表中。就我而言,我在字符串输入中找到了每个组合,并根据哈希图(O(1) 运行时)对其进行了检查。这样,运行时的增长相对于字符串输入,而不是列表输入。

      6) 检查该词是否未与好词组合使用(例如 bass 包含 *ss)。这也是通过电子表格加载的

      6) 在我们的例子中,我们还将过滤后的单词发布到 Slack,但您显然可以删除该行。

      我们在我们自己的游戏中使用它,它就像一个魅力。希望大家喜欢。

      https://pimdewitte.me/2016/05/28/filtering-combinations-of-bad-words-out-of-string-inputs/

      public static HashMap<String, String[]> words = new HashMap<String, String[]>();
      
      public static void loadConfigs() {
          try {
              BufferedReader reader = new BufferedReader(new InputStreamReader(new URL("https://docs.google.com/spreadsheets/d/1hIEi2YG3ydav1E06Bzf2mQbGZ12kh2fe4ISgLg_UBuM/export?format=csv").openConnection().getInputStream()));
              String line = "";
              int counter = 0;
              while((line = reader.readLine()) != null) {
                  counter++;
                  String[] content = null;
                  try {
                      content = line.split(",");
                      if(content.length == 0) {
                          continue;
                      }
                      String word = content[0];
                      String[] ignore_in_combination_with_words = new String[]{};
                      if(content.length > 1) {
                          ignore_in_combination_with_words = content[1].split("_");
                      }
      
      
                      words.put(word.replaceAll(" ", ""), ignore_in_combination_with_words);
                  } catch(Exception e) {
                      e.printStackTrace();
                  }
      
              }
              System.out.println("Loaded " + counter + " words to filter out");
          } catch (IOException e) {
              e.printStackTrace();
          }
      
      }
      
      
      /**
       * Iterates over a String input and checks whether a cuss word was found in a list, then checks if the word should be ignored (e.g. bass contains the word *ss).
       * @param input
       * @return
       */
      public static ArrayList<String> badWordsFound(String input) {
          if(input == null) {
              return new ArrayList<>();
          }
      
          // remove leetspeak
          input = input.replaceAll("1","i");
          input = input.replaceAll("!","i");
          input = input.replaceAll("3","e");
          input = input.replaceAll("4","a");
          input = input.replaceAll("@","a");
          input = input.replaceAll("5","s");
          input = input.replaceAll("7","t");
          input = input.replaceAll("0","o");
      
          ArrayList<String> badWords = new ArrayList<>();
          input = input.toLowerCase().replaceAll("[^a-zA-Z]", "");
      
          for(int i = 0; i < input.length(); i++) {
              for(int fromIOffset = 1; fromIOffset < (input.length()+1 - i); fromIOffset++)  {
                  String wordToCheck = input.substring(i, i + fromIOffset);
                  if(words.containsKey(wordToCheck)) {
                      // for example, if you want to say the word bass, that should be possible.
                      String[] ignoreCheck = words.get(wordToCheck);
                      boolean ignore = false;
                      for(int s = 0; s < ignoreCheck.length; s++ ) {
                          if(input.contains(ignoreCheck[s])) {
                              ignore = true;
                              break;
                          }
                      }
                      if(!ignore) {
                          badWords.add(wordToCheck);
                      }
                  }
              }
          }
      
      
          for(String s: badWords) {
              Server.getSlackManager().queue(s + " qualified as a bad word in a username");
          }
          return badWords;
      
      }
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-11-30
        • 1970-01-01
        • 2013-07-12
        • 1970-01-01
        • 1970-01-01
        • 2018-03-30
        • 2023-02-07
        • 1970-01-01
        相关资源
        最近更新 更多