为了账号安全,请及时绑定邮箱和手机立即绑定

有没有办法让 content.replace 将它们分成比这些更多的单词?

有没有办法让 content.replace 将它们分成比这些更多的单词?

一只斗牛犬 2023-12-14 16:43:54
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 过滤器代码(顶部/上方)中还是采用不同的方法?提前致谢。
查看完整描述

1 回答

?
海绵宝宝撒

TA贡献1809条经验 获得超8个赞

好吧,我不确定你想做什么.match(/\w+|\s+|[^\s\w]+/g)。这是一些不必要的正则表达式,只是为了获取单词和空格的数组。如果有人把他们的脏话分成“this”之类的东西,那根本就行不通。


如果您希望过滤器不区分大小写并考虑空格/特殊字符,更好的解决方案可能需要多个正则表达式,并对拆分字母和正常的坏词检查进行单独检查。而且你需要确保你的拆分字母检查是准确的,否则像“洗它”这样的词可能会被认为是一个坏词,尽管单词之间有空格。


一个办法


所以这是一个可能的解决方案。请注意,这只是一个解决方案,远非唯一的解决方案。我将使用硬编码的字符串示例而不是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意思是“单词边界”,本质上指示单词何时开始或停止。这包括空格、行首和行尾。\b被附加转义\(成为\\b),以防止 javascript 将正则表达式标记与字符串的转义序列混淆。

  • 两个正则表达式检查中使用的标志gi分别表示“全局”和“不区分大小写”。

当然,要使其与您的不和谐机器人一起工作,您在消息处理程序中所要做的就是这样(并且一定要替换badWordsfilter中的变量testProfanity()):

if (testProfanity(message.content)) return message.delete();

如果您想了解有关正则表达式的更多信息,或者如果您想摆弄它和/或测试它,是一个很好的资源。


查看完整回答
反对 回复 2023-12-14
  • 1 回答
  • 0 关注
  • 112 浏览
慕课专栏
更多

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信