node.js - 我希望我的漫游器删除包含关键字或包含相似字符的消息

标签 node.js string string-search string-algorithm

在我的漫游器中,我实现了一个关键字过滤器,该漫游器在聊天记录中的每条消息中均会对其进行审核,直到现在它可以正常工作,但是出于尊重的原因,我想对其进行改进,因此我不会在此处添加任何文字,因此其他一些例子

机器人会检测您是否编写了例如“粗俗”,“错误”,“你好”

但是我要实现的是检测他们是否写了“ hellooo”,“ vuulgarr”,“ vulg4rr”

这是我存储单词的基础:

badwords.js

var words = ["vulgar", "vulg4r", "hello", "badword4", "badword5"]

module.exports = words;


这是我的函数,它使用indexOf()检查是否有一个不好的单词出现,拆分所有单词,然后删除找到结果的消息。

index.js

const _ = require('lodash');
const badwords = require('./badwords');

/**
 * Functions
 */

// compares every word to badWords array from badWords.js
function checkWord(word) {
    return badwords.indexOf(word) > -1;
}

/**
 * Main Module
 */

module.exports = function (self, nick, channel, message) {
    'use strict';
    message = message.toLowerCase();
    message = message.split(' ');
    nick = nick;
    channel = channel.toLowerCase();
    for (var i = 0, len = message.length; i < len; i++) {
        if (checkWord(message[i])) {
            self.send('.ban', channel, nick);
        }
    }
}


有任何改善的想法吗?,谢谢

最佳答案

更复杂的方法

我们可以在两个字符串上都有两个指针进行比较,但是在重复项上跳过偏移量:

function checkString(message, keyword) {
    while(message.length > 0) {
        if(checkPrefix(message, keyword)) return true
        message = message.substr(1)
    }
}
function checkPrefix(message, keyword) { // keyword is one of the keywords
    let om = 0, ok = 0
    while (true) {
        if (ok >= keyword.length)
            return true // we have finished reading keyword, and everything matched
        if(om >= message.length)
            return false // message is shorter than keyword
        while (om + 1 < message.length && message.charAt(om) === message.charAt(om + 1))
            om++ // skip consecutive repetitions in message
        while (ok + 1 < keyword.length && keyword.charAt(ok) === keyword.charAt(ok + 1))
            ok++ // skip consecutive repetitions in keyword
        if (message.charAt(om) !== message.charAt(ok)) return false // encountered an inconsistent character
    }
}


一种更简单的方法

只需扫描字符串中的重复并先删除它们即可。

function removeDuplicates(string) {
    for (let i = 0; i < string.length - 1; ) {
        if (string.charAt(i) === string.charAt(i + 1)) {
            string = string.substr(0, i) + string.substr(i + 1) // skip string[i]
        } else {
            i++ // not duplicate, proceed to next pair
        }
    }
}


然后,您可以直接比较:

removeDuplicates(message).indexOf(removeDuplicates(keyword)) !== -1


您可以这样应用它:

for (const part in message.split(" ")) {
    for (word in words) {
        if (removeDuplicates(part).indexOf(removeDuplicates(word)) !== -1)
            self.send(".ban", ...)
            break
    }
}

关于node.js - 我希望我的漫游器删除包含关键字或包含相似字符的消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53840558/

相关文章:

c# - 小型集合的智能字符串搜索

postgresql - 短语搜索运算符 <-> 是否适用于 JSONB 文档或仅适用于关系表?

php - 将外来字符更改为对应的罗马字符

node.js - 在nodeJS中给出编码错误

node.js - 使用jade从文件中读取数据并传递到模板

node.js - 如何在 socket.io 客户端聊天应用程序中处理页面重新加载

node.js - 谷歌云数据存储 ORM

c - 在 C 中存储来自字符串的两个整数

c++ - 在 fscanf 中直接将 char* 转换为 std::string

java - 对于 ArrayList 中的每个项目替换为模式