【问题标题】:is there a way for the content.replace to sort of split them into more words than these?有没有办法让 content.replace 把它们分成比这些更多的词?
【发布时间】:2021-03-28 10:54:35
【问题描述】:
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'' 时删除单词 (我要添加一些过滤掉的坏词),幸运的是没有任何错误。

但现在机器人只删除这些以小写字母书写的单词,中间没有空格或特殊字符。

我想我找到了解决方案,但我似乎无法将其放入我的代码中,我的意思是我尝试了不同的方法,但它要么删除了小写单词,要么根本没有反应,而是出现了类似“”的错误无法读取 undefined'' 等的属性。

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 过滤器代码(顶部/上方)或其他方法中实现它? 提前致谢。

【问题讨论】:

    标签: javascript discord discord.js bots message


    【解决方案1】:

    好吧,我不确定你想用.match(/\w+|\s+|[^\s\w]+/g) 做什么。这是一些不必要的正则表达式,只是为了获得一组单词 空格。如果有人将他们的坏话分成“t h i s”之类的东西,它甚至都行不通。

    如果您希望过滤器不区分大小写并考虑空格/特殊字符,则更好的解决方案可能需要多个正则表达式,并分别检查拆分字母和正常的坏词检查。并且您需要确保您的拆分字母检查准确无误,否则尽管单词之间有空格,但“wash it”之类的内容可能会被视为坏词。

    解决方案

    所以这是一个可能的解决方案。请注意,它只是 a 解决方案,远非唯一的解决方案。我将使用硬编码的字符串示例而不是message.content,以允许它在工作的 sn-p 中:

    //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);

    我已经对每一行进行了彻底的注释,以便您了解我在每一行中所做的事情。又是这里,没有 cmets 或测试部件:

    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 表示“选择任何不是单词字符的字符”,其中“单词字符”是指范围 a-z、A-Z、0-9 和下划线中的字符。
    • \b 表示“单词边界”,本质上表示单词何时开始或停止。这包括空格、行首和行尾。 \b 使用额外的 \ 进行转义(变为 \\b),以防止 javascript 将正则表达式标记与字符串的转义序列混淆。
    • 两个正则表达式检查中使用的标志gi 分别表示“全局”和“不区分大小写”。

    当然,要让它与您的 discord 机器人一起工作,您在消息处理程序中所要做的就是这样(并确保将 badWords 替换为 testProfanity() 中的 filter 变量):

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

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

    【讨论】:

    • 我找到了一种方法可以让机器人删除包含大小写字母的单词,您可以在此处找到 hastebin。现在我可以将每个带有空格和特殊符号的单词放在我的过滤器代码中,但这对于每个脏话来说都需要很长时间。我所需要的只是一个代码,它可以删除“thi s”和“th.at”之类的词,但我还没有完全学习编码,尽管我确实理解了你在这些细节中解释的东西(我是很惊讶。以前从未见过!)如果可能的话,你能帮我吗?
    • 当然,您具体需要什么帮助?这个答案已经能够删除像“t h i s”和“th.at”这​​样的词。您需要做的就是将单词“this”和“that”添加到您的坏词数组中(在您的代码中,filter 数组),它不仅会删除“this”和“that”,还会删除考虑空格和特殊字符,例如“this”和“th.at”以及“that”和“th.is”。
    猜你喜欢
    • 2022-06-14
    • 2019-09-15
    • 1970-01-01
    • 2015-08-13
    • 2020-06-25
    • 2018-07-15
    • 2021-12-30
    • 2021-12-20
    • 2021-02-16
    相关资源
    最近更新 更多