const filter = ["bad1", "bad2"];
client.on("message", message => {
var content = message.content;
var stringToCheck = content.replace(/s+/g, '').toLowerCase();
for (var i = 0; i < filter.length; i++) {
if (content.includes(filter[i])){
message.delete();
break
}
}
});
所以我上面的代码是一个discordbot,当有人写"ad1"ad2"时,它会删除单词(我将添加一些经过过滤的脏话(,幸运的是没有任何错误。
但现在,机器人只会在用小写字母书写时删除这些单词,字母之间没有空格或特殊字符。
我想我已经找到了一个解决方案,但我似乎无法将其放入我的代码中,我的意思是,我尝试了不同的方法,但它要么删除了小写单词,要么根本没有反应,相反,我出现了"cannot read property of undefined"等错误。
var badWords = [
'bannedWord1',
'bannedWord2',
'bannedWord3',
'bannedWord4'
];
bot.on('message', message => {
var words = message.content.toLowerCase().trim().match(/w+|s+|[^sw]+/g);
var containsBadWord = words.some(word => {
return badWords.includes(word);
});
这就是我所看到的。var words
行。特别是CCD_ 2。
无论如何,将其实现到我的const过滤器代码中(顶部/上面(还是其他方法?提前谢谢。
好吧,我不确定你想用.match(/w+|s+|[^sw]+/g)
做什么。这是一些不必要的正则表达式,只是为了获得单词和空格的数组。如果有人把他们的脏话分解成";t h i s";。
如果您希望过滤器不区分大小写并考虑空格/特殊字符,那么更好的解决方案可能需要多个regex,并分别检查拆分字母和正常的坏字。你需要确保你的拆分字母检查是准确的,否则就像";清洗它";尽管单词之间有空格,但可能被认为是一个坏单词。
解决方案
所以这里有一个可能的解决方案。请注意,它只是一个解决方案,远远不是唯一的解决方案。我只想使用硬编码的字符串示例,而不是message.content
,以允许它出现在一个工作片段中:
//Our array of bad words
var badWords = [
'bannedWord1',
'bannedWord2',
'bannedWord3',
'bannedWord4'
];
//A function that tests if a given string contains a bad word
function testProfanity(string) {
//Removes all non-letter, non-digit, and non-space chars
var normalString = string.replace(/[^a-zA-Z0-9 ]/g, "");
//Replaces all non-letter, non-digit chars with spaces
var spacerString = string.replace(/[^a-zA-Z0-9]/g, " ");
//Checks if a condition is true for at least one element in badWords
return badWords.some(swear => {
//Removes any non-letter, non-digit chars from the bad word (for normal)
var filtered = swear.replace(/W/g, "");
//Splits the bad word into a 's p a c e d' word (for spaced)
var spaced = filtered.split("").join(" ");
//Two different regexes for normal and spaced bad word checks
var checks = {
spaced: new RegExp(`\b${spaced}\b`, "gi"),
normal: new RegExp(`\b${filtered}\b`, "gi")
};
//If the normal or spaced checks are true in the string, return true
//so that '.some()' will return true for satisfying the condition
return spacerString.match(checks.spaced) || normalString.match(checks.normal);
});
}
var result;
//Includes one banned word; expected result: true
var test1 = "I am a bannedWord1";
result = testProfanity(test1);
console.log(result);
//Includes one banned word; expected result: true
var test2 = "I am a b a N_N e d w o r d 2";
result = testProfanity(test2);
console.log(result);
//Includes one banned word; expected result: true
var test3 = "A bann_eD%word4, I am";
result = testProfanity(test3);
console.log(result);
//Includes no banned words; expected result: false
var test4 = "No banned words here";
result = testProfanity(test4);
console.log(result);
//This is a tricky one. 'bannedWord2' is technically present in this string,
//but is 'bannedWord22' really the same? This prevents something like
//"wash it" from being labeled a bad word; expected result: false
var test5 = "Banned word 22 isn't technically on the list of bad words...";
result = testProfanity(test5);
console.log(result);
我对每一行都进行了详尽的评论,这样你就可以理解我在每一行中所做的事情。它又来了,没有评论或测试部分:
var badWords = [
'bannedWord1',
'bannedWord2',
'bannedWord3',
'bannedWord4'
];
function testProfanity(string) {
var normalString = string.replace(/[^a-zA-Z0-9 ]/g, "");
var spacerString = string.replace(/[^a-zA-Z0-9]/g, " ");
return badWords.some(swear => {
var filtered = swear.replace(/W/g, "");
var spaced = filtered.split("").join(" ");
var checks = {
spaced: new RegExp(`\b${spaced}\b`, "gi"),
normal: new RegExp(`\b${filtered}\b`, "gi")
};
return spacerString.match(checks.spaced) || normalString.match(checks.normal);
});
}
解释
正如你所看到的,这个过滤器能够处理坏单词字母之间的各种标点符号、大写字母,甚至单个空格/符号。然而要注意的是;清洗它";我描述的场景(可能导致无意中删除干净的消息(;bannedWord22";将不会被视为与";bannedWord2";。如果您希望它执行相反的操作(因此将"bannedWord22"与"banned Word2"相同(,则必须删除普通检查的正则表达式中的两个\b
短语。
我还将解释正则表达式,以便您完全理解这里发生的事情:
- CCD_ 6的意思是";选择不在a-z、a-z、0-9或空格范围内的任何字符";(这意味着所有不在这些指定范围内的字符都将被一个空字符串替换,实质上是将它们从字符串中删除(
- CCD_ 7表示";选择任何不是字字符的字符";,其中";字字符";指范围a-z、a-z、0-9和下划线中的字符
- CCD_ 8表示";单词边界";,本质上指示单词何时开始或停止。这包括空格、一行的开头和一行的结尾。
b
用一个额外的(变为
\b
(进行转义,以防止javascript将正则表达式标记与字符串的转义序列混淆 - 在正则表达式检查中使用的标志CCD_ 12和CCD_;全局";以及";不区分大小写";,分别
当然,要让discord bot正常工作,您在消息处理程序中所要做的就是这样(请确保在testProfanity()
中用filter
变量替换badWords
(:
if (testProfanity(message.content)) return message.delete();
如果你想了解更多关于regex的信息,或者你想摆弄它和/或测试它,这是一个很好的资源