我想过滤一个字符串。
基本上当有人输入消息时,我希望过滤掉某些单词,如下所示:
用户类型: hey guys lol omg -omg mkdj*Omg*ndid
我希望过滤器运行并且:
输出: hey guys lol - mkdjndid
我需要从包含多个单词的ArrayList
加载过滤后的单词以进行过滤。现在我正在做if(message.contains(omg))
,但如果有人输入 zomg 或 -omg 或类似内容,则无效。
答案 0 :(得分:0)
尝试:
input.replaceAll("(\\*?)[oO][mM][gG](\\*?)", "").split(" ")
答案 1 :(得分:0)
将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 :(得分:0)
戴夫已经给了你答案,但我会在这里强调一下这句话。如果使用简单的for循环实现算法,只会替换过滤后的单词的出现,则会遇到问题。例如,如果您在单词'classic'中过滤单词ass并将其替换为'butt',则生成的单词将为'clbuttic',这没有任何意义。因此,我建议使用单词列表,如在/ usr / share / dict /目录下存储在Linux中的单词列表,以检查单词是否有效或是否需要过滤。 我不太了解你想要做的事情。
答案 3 :(得分:0)
我遇到了同样的问题,并通过以下方式解决了这个问题:
1)制作一个包含我要过滤掉的所有字词的Google电子表格
2)使用loadConfigs方法直接将google电子表格下载到我的代码中(见下文)
3)将所有l33tsp33k字符替换为各自的字母
4)替换所有特殊字符,但替换句子中的字母
5)运行一种算法,该算法可以有效地检查字符串中所有可能的单词组合,注意这部分是关键 - 你不想每次都在你的整个列表上循环,看看你的单词在列表中。在我的例子中,我找到了字符串输入中的每个组合,并根据散列图(O(1)运行时)对其进行了检查。这样,运行时相对于字符串输入而不是列表输入增长。
6)检查单词是否与好词结合使用(例如,贝司包含* 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;
}