实时检测字符串是否包含MySQL数据库中的词汇
解决MySQL词汇库实时检测字符串的问题
首先看你现有代码的核心问题:desc.toLowerCase().includes(result)这行根本不生效,因为result是数据库返回的结果对象数组(每个元素是包含word字段的对象),不是单个字符串,而且includes方法只能检查是否包含单个值,没法直接匹配数组里的所有元素。
接下来分两种场景给你解决方案,同时满足「新增词汇无需重启脚本」的需求:
场景1:词汇量较小(实时查询数据库)
如果你的词汇库条目不多,每次检测时直接查询数据库是最简单的方案,这样新增的词汇会立刻被检测到,不需要额外缓存。
修正后的代码如下:
var desc = 'you are a stupid man'; db.connect((err) => { if (err) throw err; console.log('Connected!'); // 1. 查询所有词汇 let sql = 'SELECT `word` FROM `words`'; db.query(sql, (err, results) => { if (err) throw err; // 2. 把查询结果转成小写的词汇数组(统一大小写避免匹配遗漏) const forbiddenWords = results.map(item => item.word.toLowerCase()); // 3. 遍历数组,找出所有被字符串包含的禁用词 const matchedWords = forbiddenWords.filter(word => desc.toLowerCase().includes(word)); if (matchedWords.length > 0) { // 输出所有检测到的词汇 console.log(`Don't use words like ${matchedWords.join(', ')}`); } else { console.log('No forbidden words detected.'); } }); });
关键改动点:
- 用
map把数据库返回的结果转成纯词汇数组,同时统一转小写保证大小写无关匹配 - 用
filter遍历数组,筛选出所有被目标字符串包含的禁用词 - 通过匹配结果的长度判断是否存在违规词汇
场景2:词汇量较大(定时刷新本地缓存)
如果词汇库条目很多,每次检测都查数据库会影响性能,这时候可以把词汇缓存到本地,然后定时刷新缓存(比如每分钟刷新一次),这样既保证性能,又能在新增词汇后短时间内生效,完全不需要重启脚本。
示例代码:
var desc = 'you are a stupid man'; let forbiddenWordsCache = []; // 本地缓存数组 // 定义刷新缓存的函数 function refreshForbiddenWords() { let sql = 'SELECT `word` FROM `words`'; db.query(sql, (err, results) => { if (err) { console.error('Failed to refresh forbidden words:', err); return; } forbiddenWordsCache = results.map(item => item.word.toLowerCase()); console.log('Forbidden words cache refreshed.'); }); } // 初始化连接并首次加载缓存 db.connect((err) => { if (err) throw err; console.log('Connected!'); refreshForbiddenWords(); // 定时刷新缓存,比如每60秒一次(时间可自行调整) setInterval(refreshForbiddenWords, 60 * 1000); }); // 封装检测字符串的函数 function checkForForbiddenWords(str) { const lowerStr = str.toLowerCase(); const matchedWords = forbiddenWordsCache.filter(word => lowerStr.includes(word)); if (matchedWords.length > 0) { console.log(`Don't use words like ${matchedWords.join(', ')}`); return true; } console.log('No forbidden words detected.'); return false; } // 调用检测函数 checkForForbiddenWords(desc);
这个方案的优势:
- 大部分检测操作直接用本地缓存,性能更优
- 定时刷新缓存,新增的词汇会在下次刷新后自动生效
- 全程不需要重启脚本即可获取最新词汇
额外提示:
- 如果需要做完整单词匹配(比如避免把"stupid"和"stupidity"混淆),可以改用正则表达式实现,示例如下:
const matchedWords = forbiddenWordsCache.filter(word => { const regex = new RegExp(`\\b${word}\\b`, 'i'); // \b 表示单词边界,i 表示忽略大小写 return regex.test(str); }); - 注意完善数据库查询的错误处理,避免因数据库连接问题导致脚本崩溃。
内容的提问来源于stack exchange,提问作者nih
相关产品推荐
相关产品推荐

