javascript - 有没有办法让 content.replace 把它们分成比这些更多的词?
问题描述
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
}
}
});
所以我上面的代码是一个不和谐的机器人,当有人写 ''bad1'' ''bad2'' 时删除单词(我要添加一些过滤掉的坏词),幸运的是没有任何错误。
但现在,机器人只会在以小写字母书写时删除这些单词,中间没有空格或特殊字符。
我想我找到了解决方案,但似乎无法将其放入我的代码中,我的意思是我尝试了不同的方法,但它要么删除了小写单词,要么根本没有反应,而是出现类似“无法读取属性”之类的错误未定义的''等
var badWords = [
'bannedWord1',
'bannedWord2',
'bannedWord3',
'bannedWord4'
];
bot.on('message', message => {
var words = message.content.toLowerCase().trim().match(/\w+|\s+|[^\s\w]+/g);
var containsBadWord = words.some(word => {
return badWords.includes(word);
});
这就是我正在看的。线var words
。具体来说(/\w+|\s+|[^\s\w]+/g);
。
无论如何要将其实现到我的 const 过滤器代码(顶部/上方)或不同的方法中?提前致谢。
解决方案
好吧,我不确定你要做什么.match(/\w+|\s+|[^\s\w]+/g)
。这是一些不必要的正则表达式,只是为了获得一组单词和空格。如果有人将他们的坏话分成“this s”之类的东西,它甚至都行不通。
如果您希望过滤器不区分大小写并考虑空格/特殊字符,则更好的解决方案可能需要多个正则表达式,并分别检查拆分字母和正常的坏词检查。而且你需要确保你的拆分字母检查是准确的,否则尽管单词之间有空格,但像“洗它”这样的东西可能会被认为是一个坏词。
一个办法
所以这是一个可能的解决方案。请注意,它只是一个解决方案,远非唯一的解决方案。我将使用硬编码的字符串示例而不是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”视为与“bannedWord2”相同),则必须删除\\b
正常检查的正则表达式中的两个短语。
我还将解释正则表达式,以便您完全理解这里发生的事情:
[^a-zA-Z0-9 ]
表示“选择不在 az、AZ、0-9 或空格范围内的任何字符”(这意味着不在这些指定范围内的所有字符都将被替换为空字符串,实质上是将它们从字符串中删除)。\W
表示“选择任何不是单词字符的字符”,其中“单词字符”是指范围 az、AZ、0-9 和下划线中的字符。\b
意思是“单词边界”,本质上表示单词何时开始或停止。这包括空格、行首和行尾。为了防止 javascript 将正则表达式标记与字符串的转义序列混淆,\b
使用附加\
(to become ) 进行转义。\\b
- 两个正则表达式检查中使用的标志
g
和i
分别表示“全局”和“不区分大小写”。
当然,要让它与您的不和谐机器人一起工作,您在消息处理程序中要做的就是这样(并确保badWords
用您的filter
变量 in替换testProfanity()
):
if (testProfanity(message.content)) return message.delete();
如果您想了解更多关于正则表达式的信息,或者如果您想弄乱它和/或测试它,这是一个很好的资源。
推荐阅读
- c - 为什么我们在扫描c语言输入的字符串时不在scanf中指定'&'符号?
- javascript - 如何在 skulpt 中停止脚本
- javascript - 通用类型数组 lint 警告 Array<>
- c++ - 在最少的操作中实现字符串所有字符的相同频率。(所有字符都从 'a' 到 'z')
- c# - wpf 使用 bitmapimage 作为 TransformedBitmap 的源
- java - 如何将 UTF-16 编码的 char 转换为 CP855 编码的 char?
- wordpress - 每个术语分类一个帖子
- performance - 为什么程序永远不会在完全相同的时间执行?
- django - 重定向到 https django 后出现 502 错误网关
- entity-framework - 禁用延迟加载时,如何仅将导航属性的特定属性包含到实体框架的查询中?