1

我想过滤一个字符串。

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

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

我希望过滤器运行并且:

输出: hey guys lol - mkdjndid

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

4

4 回答 4

1

Use replaceAll with a regex built from the bad word:

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

This passes your test case:

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 );
}
于 2012-06-18T02:44:39.567 回答
0

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

于 2012-06-18T13:27:59.163 回答
0

尝试:

input.replaceAll("(\\*?)[oO][mM][gG](\\*?)", "").split(" ")
于 2012-06-18T02:15:19.070 回答
0

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

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;

}
于 2016-05-29T11:16:19.377 回答