есть ли способ для content.replace разделить их на большее количество слов, чем эти?

#javascript #discord #discord.js #bots #message

#javascript #Discord #discord.js #боты #Сообщение

Вопрос:

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

Итак, мой приведенный выше код — это бот discord, который удаляет слова, когда кто-то пишет «bad1» «bad2»
(еще несколько отфильтрованных плохих слов, которые я собираюсь добавить), и, к счастью, никаких ошибок.

Но прямо сейчас бот удаляет эти слова только тогда, когда они написаны маленькими буквами без пробелов между ними или специальных символов.

Я думаю, что нашел решение, но, похоже, я не могу вставить его в свой код, я имею в виду, что я пробовал разные способы, но он либо удалял строчные слова, либо вообще не реагировал, и вместо этого я получал ошибки типа «невозможно прочитать свойство 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 строка. в частности (/w |s |[^sw] /g); .

В любом случае, чтобы реализовать это в моем коде const filter (top / above) или другой подход? Заранее спасибо.

Ответ №1:

Ну, я не уверен, с чем вы пытаетесь это сделать .match(/w |s |[^sw] /g) . Это какое-то ненужное регулярное выражение только для получения массива слов и пробелов. И это даже не сработает, если кто-то разделит свое плохое слово на что-то вроде «это».

Если вы хотите, чтобы ваш фильтр не учитывал регистр и учитывал пробелы / специальные символы, лучшее решение, вероятно, потребует более одного регулярного выражения, а также отдельных проверок на разделенные буквы и обычной проверки неверных слов. И вам нужно убедиться, что ваша проверка на разделение букв верна, иначе что-то вроде «wash it» может считаться плохим словом, несмотря на пробел между словами.

Решение

Итак, вот возможное решение. Обратите внимание, что это всего лишь решение, и оно далеко не единственное. Я просто собираюсь использовать жестко запрограммированные строковые примеры вместо 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 resu<

//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 ] означает «выберите любой символ, не входящий в диапазоны от а до Я, от А до Я, 0-9 или пробел» (это означает, что все символы, не входящие в указанные диапазоны, будут заменены пустой строкой, по существу удаляя их из строки).
  • W означает «выбрать любой символ, который не является символом слова», где «символ слова» относится к символам в диапазонах от а до Я, от А до Я, 0-9 и подчеркивание.
  • b означает «границу слова», по сути, указывая, когда начинается или заканчивается слово. Это включает пробелы, начало строки и конец строки. b экранируется дополнительным (to become \b ), чтобы javascript не путал токен регулярного выражения с escape-последовательностями строк.
  • Флаги g и i , используемые в обеих проверках регулярных выражений, указывают на «глобальный» и «нечувствительный к регистру» соответственно.

Конечно, чтобы заставить это работать с вашим ботом discord, все, что вам нужно сделать в вашем обработчике сообщений, это что-то вроде этого (и обязательно замените badWords на свою filter переменную в testProfanity() ):

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

Если вы хотите узнать больше о регулярных выражениях или хотите поработать с ним и / или протестировать его, это отличный ресурс для этого.

Комментарии:

1. Я нашел способ заставить бота удалять слова, в которых есть строчные и прописные буквы, которые вы можете найти здесь hastebin . На данный момент я мог бы просто поместить каждое слово с пробелами и специальными символами между ними в свой код для фильтра, но это заняло бы целую вечность для каждого ругательного слова. все, что мне нужно, это код, который удаляет такие слова, как «t h i s» и что-то вроде «th.at «но я еще не до конца изучил программирование, хотя и понял то, что вы так подробно объяснили (я поражен. никогда не видел этого раньше!) Не могли бы вы помочь мне, пожалуйста, если это возможно?

2. Конечно, с чем конкретно вам нужна помощь? Этот ответ уже способен удалять такие слова, как «t h i s» и «th.at «. Все, что вам нужно сделать, это добавить слова «this» и «that» к вашему массиву плохих слов (в вашем коде, filter массиве), и это не только удалит «this» и «that», но также учтет пробелы и специальные символы, такие как «t h i s» и «th.at «и «т а т» и «th.is «.