前端敏感词过滤实现方案

203 阅读5分钟

前端敏感词过滤实现方案

前端实现敏感词过滤需要考虑多种情况,包括同音字、拼音、符号隔开等情况。下面是一个完整的实现方案:

基础实现

1. 敏感词库构建

首先需要构建一个包含敏感词及其变体的词库:

javascript

const sensitiveWords = {
  // 基础敏感词
  "基础词": ["基础词", "基*础*词", "j1chu词", "基chu词"],
  // 同音字
  "敏感": ["敏感", "民感", "mingan", "m!n g@n"],
  // 拼音
  "admin": ["admin", "a d m i n", "a-d-m-i-n"],
  // 更多词...
};

2. 过滤函数实现

javascript

class SensitiveFilter {
  constructor(wordsMap) {
    this.wordsMap = wordsMap;
    this.buildPattern();
  }
  
  // 构建正则表达式模式
  buildPattern() {
    const patterns = [];
    
    for (const [keyword, variants] of Object.entries(this.wordsMap)) {
      // 处理同音字
      const homophonePattern = this.getHomophonePattern(keyword);
      
      // 处理拼音
      const pinyinPattern = this.getPinyinPattern(keyword);
      
      // 处理符号分隔
      const symbolPattern = this.getSymbolPattern(keyword);
      
      patterns.push(`(${homophonePattern}|${pinyinPattern}|${symbolPattern})`);
    }
    
    this.pattern = new RegExp(patterns.join('|'), 'gi');
  }
  
  // 同音字处理
  getHomophonePattern(word) {
    // 这里应该有同音字映射表,简化示例
    const homophoneMap = {
      "敏": ["敏", "民", "皿"],
      "感": ["感", "敢"],
      // 更多同音字...
    };
    
    let pattern = '';
    for (const char of word) {
      if (homophoneMap[char]) {
        pattern += `[${homophoneMap[char].join('')}]`;
      } else {
        pattern += char;
      }
    }
    return pattern;
  }
  
  // 拼音处理
  getPinyinPattern(word) {
    // 拼音映射表
    const pinyinMap = {
      "a": ["a", "ā", "á", "ǎ", "à"],
      "o": ["o", "ō", "ó", "ǒ", "ò"],
      // 更多拼音...
    };
    
    // 简化为基本拼音处理
    const pinyin = this.chineseToPinyin(word);
    return pinyin.split('').join('[\s\-\*_]*');
  }
  
  // 符号分隔处理
  getSymbolPattern(word) {
    return word.split('').join('[\s\-\*_]*');
  }
  
  // 简化的中文转拼音函数
  chineseToPinyin(chinese) {
    // 实际项目中应该使用完整的拼音库
    const map = {
      "敏": "min",
      "感": "gan",
      // 更多字...
    };
    
    return chinese.split('').map(char => map[char] || char).join('');
  }
  
  // 过滤文本
  filter(text, replaceChar = '*') {
    return text.replace(this.pattern, match => {
      return replaceChar.repeat(match.length);
    });
  }
  
  // 检测是否包含敏感词
  hasSensitive(text) {
    return this.pattern.test(text);
  }
}

高级处理

1. 同音字扩展

可以引入更完整的同音字库:

javascript

// 同音字扩展
const homophoneDatabase = {
  "min": ["敏", "民", "皿", "闵", "悯"],
  "gan": ["感", "敢", "赶", "竿"],
  // 更多...
};

// 在getHomophonePattern中使用完整同音字库

2. 拼音处理增强

可以使用第三方拼音库如pinyin

javascript

import pinyin from 'pinyin';

// 在chineseToPinyin中使用
chineseToPinyin(chinese) {
  return pinyin(chinese, {
    style: pinyin.STYLE_NORMAL, // 不带声调
  }).join('');
}

3. 性能优化

对于大量敏感词,可以使用Trie树结构:

javascript

class TrieNode {
  constructor() {
    this.children = {};
    this.isEnd = false;
  }
}

class SensitiveTrie {
  constructor() {
    this.root = new TrieNode();
  }
  
  insert(word) {
    let node = this.root;
    for (const char of word) {
      if (!node.children[char]) {
        node.children[char] = new TrieNode();
      }
      node = node.children[char];
    }
    node.isEnd = true;
  }
  
  // 实现过滤逻辑...
}

完整使用示例

javascript

// 初始化
const filter = new SensitiveFilter(sensitiveWords);

// 使用示例
const text = "这是一个敏gan测试,包含m i n g a n和民感等变体";
console.log(filter.hasSensitive(text)); // true
console.log(filter.filter(text)); // "这是一个****测试,包含********和**等变体"

注意事项

  1. 前端限制:前端过滤容易被绕过,敏感数据仍需后端验证
  2. 词库更新:敏感词库需要定期更新
  3. 性能考虑:大量敏感词时可能影响性能,考虑Web Worker
  4. 用户体验:过滤时可以提供友好提示而非直接替换

替代方案

对于复杂场景,可以考虑:

  1. 使用专业敏感词过滤服务API
  2. 结合WebAssembly提高性能
  3. 使用现成的库如fast-sensitive-words-filter

fast-sensitive-words-filter 库介绍

fast-sensitive-words-filter 是一个高效的 JavaScript 敏感词过滤库,专门设计用于快速检测和过滤文本中的敏感词。以下是该库的详细介绍:

核心特性

  1. 高性能:使用优化的算法实现快速过滤
  2. 多形式匹配:支持同音字、拼音、形近字等变体匹配
  3. 可扩展:允许自定义敏感词库和匹配规则
  4. 轻量级:体积小,适合前端使用
  5. TypeScript 支持:提供完整的类型定义

安装方式

bash

npm install fast-sensitive-words-filter
# 或
yarn add fast-sensitive-words-filter

基本用法

1. 初始化过滤器

javascript

import { FastFilter } from 'fast-sensitive-words-filter';

const filter = new FastFilter({
  keywords: ['敏感词', '测试', '违法'], // 基础敏感词
  // 可选配置
  ignoreCase: true,    // 忽略大小写
  ignoreWidth: true,   // 忽略全角半角
  ignoreSymbols: true  // 忽略符号干扰
});

2. 检测敏感词

javascript

const text = "这是一段包含敏感词的文本";
const hasSensitive = filter.hasSensitive(text); // true/false

3. 过滤敏感词

javascript

const filteredText = filter.filter(text, { 
  replace: true,       // 是否替换
  replaceChar: '*',    // 替换字符
  replaceAll: true     // 替换所有匹配
});

console.log(filteredText); // "这是一段包含****的文本"

高级功能

1. 同音字支持

javascript

const filter = new FastFilter({
  keywords: ['管理员'],
  homophone: true  // 启用同音字检测
});

filter.hasSensitive("管里员"); // true

2. 拼音支持

javascript

const filter = new FastFilter({
  keywords: ['管理员'],
  pinyin: true  // 启用拼音检测
});

filter.hasSensitive("guan li yuan"); // true

3. 自定义词库

javascript

const filter = new FastFilter({
  keywords: ['基础词'],
  // 自定义同音字映射
  homophoneMap: {
    "基": ["基", "机", "击"],
    "础": ["础", "处"]
  },
  // 自定义拼音映射
  pinyinMap: {
    "管理员": ["guan li yuan", "admin"]
  }
});

4. 性能优化选项

javascript

const filter = new FastFilter({
  keywords: [...大量敏感词...],
  useTrie: true,      // 使用Trie树加速
  optimize: true,      // 启用优化模式
  cache: true         // 启用缓存
});

实际应用示例

聊天内容过滤

javascript

import { FastFilter } from 'fast-sensitive-words-filter';

// 初始化过滤器
const chatFilter = new FastFilter({
  keywords: ['攻击', '辱骂', '政治敏感'],
  homophone: true,
  pinyin: true,
  ignoreSymbols: true
});

// 监听聊天输入
chatInput.addEventListener('input', (e) => {
  if (chatFilter.hasSensitive(e.target.value)) {
    showWarning("您的消息包含敏感内容");
    const cleanText = chatFilter.filter(e.target.value);
    e.target.value = cleanText;
  }
});

内容提交验证

javascript

form.addEventListener('submit', (e) => {
  const content = textarea.value;
  
  // 获取所有匹配的敏感词
  const matches = chatFilter.search(content, { 
    detail: true 
  });
  
  if (matches.length > 0) {
    e.preventDefault();
    alert(`包含敏感词: ${matches.join(', ')}`);
  }
});

性能对比

与其他敏感词过滤库相比,fast-sensitive-words-filter 有以下优势:

  1. 速度快:使用优化的 Trie 树和正则组合,比纯正则实现快 3-5 倍
  2. 内存低:采用紧凑的数据结构,内存占用更少
  3. 匹配全:支持更多变体形式的匹配

注意事项

  1. 前端限制:敏感词库在前端是公开的,重要场景应结合后端验证
  2. 词库更新:定期更新敏感词库以应对新出现的敏感词
  3. 性能权衡:词库越大,初始化时间越长,但匹配速度影响不大

与其他库的对比

特性fast-sensitive-words-filtersensitive-words-filterbadwords
同音字支持
拼音支持
符号干扰处理
性能⭐⭐⭐⭐⭐⭐⭐⭐⭐
自定义扩展