In content platform development, sensitive word filtering is an indispensable function. Traditional string replacement methods have poor performance w...
Go implements high-performance sensitive word filtering system
Published: 2025-07-29 (a year ago)
GO

在内容平台开发中,敏感词过滤是必不可少的功能。传统的字符串替换方法在面对大量敏感词时性能低下,而本文将介绍如何使用 AC 自动机算法实现一个高性能的敏感词过滤系统。

✨ 核心特性

🚀 高性能算法

  • AC 自动机:基于 Aho-Corasick 算法,时间复杂度 O(n)
  • 一次扫描:单次遍历即可检测所有敏感词
  • 内存优化:使用 Trie 树结构,空间效率高

🎯 智能检测

  • 词边界检测:避免"草莓"被"草"误判的问题
  • 正则表达式支持:灵活处理手机号、邮箱等模式
  • 中英文混合:支持中文、英文、数字的边界判断

🔒 并发安全

  • 读写锁:支持多协程并发访问
  • 线程安全:生产环境可靠运行

🏗️ 系统架构

核心组件

Go Copy
type SensitiveFilter struct {
    matcher    *cedar.Matcher      // AC自动机匹配器
    regexRules map[string]string   // 正则规则映射
    mu         sync.RWMutex        // 读写锁
}

工作流程

  1. 初始化阶段:从文件加载敏感词,构建 AC 自动机
  2. 检测阶段:使用 AC 自动机快速匹配 + 正则规则补充
  3. 过滤阶段:替换敏感词并保证不重复处理

💡 核心实现

1. AC 自动机构建

Go Copy
func NewSensitiveFilter() *SensitiveFilter {
    words := loadWordsFromFile()
    regexRules := loadRegexRules()

    // 构建AC自动机
    m := cedar.NewMatcher()
    for i, word := range words {
        m.Insert([]byte(word), i)
    }
    m.Compile() // 编译自动机

    return &SensitiveFilter{
        matcher:    m,
        regexRules: regexRules,
    }
}

2. 智能词边界检测

Go Copy
func (f *SensitiveFilter) isWordBoundary(text, word string) bool {
    index := strings.Index(text, word)
    if index == -1 {
        return false
    }

    // 检查前边界
    if index > 0 {
        prevChar := rune(text[index-1])
        if f.isWordChar(prevChar) {
            return false
        }
    }

    // 检查后边界
    endIndex := index + len(word)
    if endIndex > len(text) {
        nextChar := rune(text[endIndex])
        if f.isWordChar(nextChar) {
            return false
        }
    }

    return true
}

3. 高效过滤算法

Go Copy
func (f *SensitiveFilter) Filter(text string) string {
    f.mu.RLock()
    defer f.mu.RUnlock()

    seq := []byte(text)
    resp := f.matcher.Match(seq)
    defer resp.Release()

    replaced := make(map[string]struct{})
    for resp.HasNext() {
        items := resp.NextMatchItem(seq)
        for _, itr := range items {
            wordBytes := f.matcher.Key(seq, itr)
            word := string(wordBytes)

            if _, exists := replaced[word]; !exists {
                text = strings.ReplaceAll(text, word, "########")
                replaced[word] = struct{}{}
            }
        }
    }

    // 正则规则补充
    for pattern, replacement := range f.regexRules {
        re := regexp.MustCompile(pattern)
        text = re.ReplaceAllString(text, replacement)
    }

    return text
}

📊 性能优势

算法复杂度对比

方法 时间复杂度 空间复杂度 适用场景
暴力匹配 O(n×m×k) O(1) 敏感词少
KMP算法 O(n×k) O(m) 单词匹配
AC自动机 O(n) O(m×k) 多词匹配

🛡️ 安全特性

1. 正则规则扩展

Go Copy
regexRules := map[string]string{
    `\d{11}`:   "[手机号]",  // 手机号脱敏
    `(?i)test`: "***",      // 不区分大小写
}

2. 并发安全保障

Go Copy
func (f *SensitiveFilter) Check(text string) bool {
    f.mu.RLock()
    defer f.mu.RUnlock()
    // 安全的并发检测
}

🚀 使用示例

基础用法

Go Copy
// 初始化过滤器
filter := sensitive_ser.NewSensitiveFilter()

// 检测敏感词
hasSensitive := filter.Check("这是一段测试文本")

// 过滤敏感词
cleanText := filter.Filter("这是一段包含敏感词的文本")

集成到业务系统

Go Copy
// 在聊天系统中使用
func HandleMessage(info ClientInfo, content string) {
    // 过滤敏感词
    filterContent := global.SensitiveFilter.Filter(content)
    
    // 广播清洁内容
    Broadcast(filterContent)
}