【问题标题】:Replacing and trimming messages替换和修剪消息
【发布时间】:2020-06-12 00:25:30
【问题描述】:

我正在尝试 toLowerCase,替换然后修剪该替换,例如 Hello [- the re _- wo rl d. 将变成一个没有空格或标点符号的字符串 hellothereworld

我正在使用这个

    let msg = message.content.toLowerCase()
    let originalMessage = msg.split(" ");
    let removePunctuation = originalMessage.toString().replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g,"");
    let checkMessage = removePunctuation.toString().trim();

然后这个来过滤消息:

for (let i = 0; i < checkMessage.length; i++) {
    if(allowed.includes(checkMessage[i])) {
        continue;
    }
    if(curse.includes(checkMessage[i])) {
        const filterViolation = new Discord.RichEmbed()
            .setColor('#ff0000')
            .setAuthor(message.author.username, message.author.avatarURL)
            .setTitle('Filter Violation')
            .setDescription(`${rule} **Profanity.** \n${ifcont}\n${ifmistake}`)
            .setTimestamp()
            .setFooter(copyright);
        message.delete()
        message.author.send(filterViolation)
        message.channel.send(msgvio).then(msg => {msg.delete(15000)})
        logger.write(logviolation)
    }
//More code
}

感谢 Tarazed 对过滤器的总体帮助。

但是当我输入任何违反过滤器的消息时,什么都不会发生,控制台中也不会抛出任何错误。关于我做错了什么有什么想法吗?

新代码:

let checkMessage = message.content.toLowerCase().replace(/[^\w ]/g,"");

    console.log(checkMessage);

    // let checkMessage = msg.split(" ");
    for (let i = 0; i < checkMessage.length; i++) {
    if(checkMessage.includes(allowed[i])) {
        continue;
    }
//--------------------------------------- CURSE
    if(checkMessage.includes(curse[i])) {
        const filterViolation = new Discord.RichEmbed()
            .setColor('#ff0000')
            .setAuthor(message.author.username, message.author.avatarURL)
            .setTitle('Filter Violation')
            .setDescription(`${rule} **Profanity.** \n${ifcont}\n${ifmistake}`)
            .setTimestamp()
            .setFooter(copyright);
        message.delete()
        message.author.send(filterViolation)
        message.channel.send(msgvio).then(msg => {msg.delete(15000)})
        logger.write(logviolation)
    }
}

它正确记录了检查消息console.log(checkMessage);,但它没有通过过滤器,既不允许也不允许。

它正确记录了消息,但单词违反了过滤器,但什么也没做。

新代码 2:

if(curse.some(word => checkMessage.includes(word) && !allowed.some(allow => allow.includes(word) && checkMessage.includes(allow)))) {
        const filterViolation = new Discord.RichEmbed()
            .setColor('#ff0000')
            .setAuthor(message.author.username, message.author.avatarURL)
            .setTitle('Filter Violation')
            .setDescription(`${rule} **Profanity.** \n${ifcont}\n${ifmistake}`)
            .setTimestamp()
            .setFooter(copyright);
        message.delete()
        message.author.send(filterViolation)
        message.channel.send(msgvio).then(msg => {msg.delete(15000)})
        logger.write(logviolation)
        return;
    }

【问题讨论】:

  • 您是否在任何时候登录checkMessage 以确保它符合您的期望...?
  • 是的,我是,当我输入“t - e st”时,它会记录“test”
  • 这是您所期待的吗?正如我现在看到的那样,您循环遍历每个字符(在checkMessage 中)以检查它是否在允许的字符中,但是如果“坏”字符已经被过滤掉了,那又有什么意义呢?
  • 您可以简化正则表达式以将非字母数字字符替换为/[\W]/
  • @PrinceBunBun981 您没有告诉它要替换什么,该代码只会将第一个字符替换为 undefined - 请参阅我的答案以了解正确用法

标签: javascript discord.js


【解决方案1】:

由于checkMessage 是一个字符串,您的for 循环正在循环并测试单个字符。

例如:

let checkMessage = "hellothereworld";
for (let i = 0; i < checkMessage.length; i++) {
    console.log(checkMessage[i]);
}

也许您宁愿保留字符串中的空格并对单个单词进行操作:

let originalMessage = "Hello [-the world"


// Use regex that keeps spaces
let removePunctuation = originalMessage.toString().replace(/[^\w ]/g,"");
let checkMessage = removePunctuation.toString().trim();

// Split into words
let messageArray = checkMessage.split(' ');

// Loop over words
for (let i = 0; i < messageArray.length; i++) {
    console.log(messageArray[i]);
}

【讨论】:

    【解决方案2】:

    您当前的问题是,您实际上只是在迭代像 "test" 这样的字符串,并检查每个字母是否是诅咒词。

    也就是说,checkMessage[0] 将是 't'checkMessage[1] 将是 'e',等等。我猜没有一个字符可以匹配您的 curse 甚至 allowed 数组中的任何内容。

    您可以完全摆脱循环,只需检查if(curse.includes(checkMessage)),整个消息...但要小心,这可能很容易返回误报。天堂禁止有人发送像 "it was a nice pic until i looked closer"pic until 这样的消息会在您的过滤器中触发某个 c-word。

    无论如何,我还想指出,您用于去除空格和标点符号的代码做了一些相当奇怪的事情。我将评论我期望在每个阶段发生的事情。假设输入消息为" Hello - world. "

    let originalMessage = msg                    //" hello - world. "
                           .split(" ");          //["", "hello", "-", "world.", ""]
    let removePunctuation = originalMessage
                             .toString()         //",hello,-,world.," (why even split?)
                             .replace(/[.,\/#!$%\^&\*;:{}=\-_`~()]/g,""); //"helloworld"
    let checkMessage = removePunctuation
                        .toString() //"helloworld" (does nothing ever)
                        .trim();    //"helloworld" (does nothing ever)
    

    您可以通过使用匹配所有非单词字符的正则表达式类\W 轻松实现相同的目的:

    let checkMessage = message.content.toLowerCase().replace(/\W/g,""); //"helloworld"
    

    看起来仍然存在与循环相关的问题。我建议使用Array#some 来测试消息是否包含任何脏话:

    let checkMessage = message.content.toLowerCase().replace(/[^\w ]/g,"");
    
    if(curse.some(word =>                //search through the curse words
         checkMessage.includes(word) &&  //if message has this curse word
         !allowed.some(allow =>          //and there's no allowed word which:
           allow.includes(word) &&       //1. contains this curse word
           checkMessage.includes(allow)  //2. is in the message
         )
      )) {
      //then send violation
    }
    

    【讨论】:

    • 这对删除标点符号的部分起到了作用,但就像 Ed Lucas 所说的那样,使用 /[^\w ]/g,"" 不会做空格。我考虑了你关于“图片直到”的例子,这是一个非常有效的观点。所以我有了,但它仍然没有贯穿整个过滤器。
    • @PrinceBunBun981 所以它仍然不起作用?如果是这样,我建议在您的新代码中编辑问题以及任何控制台输出,它应该可以处理这些更改
    • @PrinceBunBun981 看到我的编辑。我可能误解了您的 allow 数组的目的,但我认为它是包含诅咒词作为子字符串但不应触发违规的词。如果这不正确,请告诉我。
    • 是的,没错,改成这样,现在它发送了 4 次违规。抱歉,如果这让您感到厌烦。这是错误的图片link
    • @PrinceBunBun981 看起来你还在循环中。它不应再处于任何形式的循环中。请删除 .some() 以外的所有循环,并确保在发送违规消息后return
    猜你喜欢
    • 2010-09-29
    • 2013-09-25
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-01-18
    • 2018-12-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多