惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

T
Threat Research - Cisco Blogs
OSCHINA 社区最新新闻
OSCHINA 社区最新新闻
The Register - Security
The Register - Security
A
About on SuperTechFans
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
L
LangChain Blog
N
Netflix TechBlog - Medium
量子位
博客园 - 三生石上(FineUI控件)
宝玉的分享
宝玉的分享
H
Help Net Security
D
Docker
D
DataBreaches.Net
T
Tailwind CSS Blog
阮一峰的网络日志
阮一峰的网络日志
B
Blog
博客园 - 聂微东
Apple Machine Learning Research
Apple Machine Learning Research
Google DeepMind News
Google DeepMind News
The Cloudflare Blog
F
Full Disclosure
GbyAI
GbyAI
F
Fortinet All Blogs
Last Week in AI
Last Week in AI
Y
Y Combinator Blog
人人都是产品经理
人人都是产品经理
Recent Announcements
Recent Announcements
博客园 - Franky
MongoDB | Blog
MongoDB | Blog
有赞技术团队
有赞技术团队
博客园 - 叶小钗
小众软件
小众软件
V
Visual Studio Blog
月光博客
月光博客
Stack Overflow Blog
Stack Overflow Blog
The GitHub Blog
The GitHub Blog
Recorded Future
Recorded Future
J
Java Code Geeks
雷峰网
雷峰网
P
Privacy & Cybersecurity Law Blog
C
Cisco Blogs
C
Cyber Attacks, Cyber Crime and Cyber Security
AWS News Blog
AWS News Blog
Webroot Blog
Webroot Blog
美团技术团队
N
News | PayPal Newsroom
G
Google Developers Blog
Security Archives - TechRepublic
Security Archives - TechRepublic
博客园_首页
V
Vulnerabilities – Threatpost

博客园 - 君之蘭

WPF打印票据 easyui plugin——etreegrid:CRUD Treegrid 【经验谈】XmlSerializer的坑 从抽象谈起(三):AOP编程和ASP.NET MVC 从抽象谈起(二):观察者模式与回调 从抽象谈起(一):工厂模式与策略模式 SQL SERVER BI 入门:(2) Analysis Service 应用 SQL SERVER BI 入门:(1)安装与基础概念 HTML5 Canvas编写五彩连珠(6):试玩 HTML5 Canvas编写五彩连珠(5):寻路 HTML5 Canvas编写五彩连珠(4):动画 HTML5 Canvas编写五彩连珠(3):设计 HTML5 Canvas编写五彩连珠(2):画图 HTML5 Canvas编写五彩连珠(1):预览 带你走进缓存世界(6):共享缓存 ASP.NET MVC3 Custom FormAuthorize ASP.NET MVC3 Custom ErrorPages 500/404 带你走进缓存世界(5):一显身手 带你走进缓存世界(4):缓存之缓
Trie树-脏词过滤应用
君之蘭 · 2011-11-25 · via 博客园 - 君之蘭

Trie树,又称字符查找树、前缀树,主要用于字符匹配(详见http://en.wikipedia.org/wiki/Trie)。适合做关键词查找,比如查找文章中的关键字然后给他们加链接。 当然对脏词的过滤应用也是样,只是把替换连接的工作换成了替换字符。

当前的代码还只是进行简单的替换,并没有做一些字符的处理,比如“昨天见到你妈,逼我要买房”,这本身不是脏词,因为有逗号,所以程序里要增加字符的范围判断。

程序中的skip就是用来过滤脏词的简单变体,比如“找*小*姐”,默认是最多跳过3个字符,这个可以随便调整了。总之是一个Trie的锻炼吧。

    public class TrieTree
    {
        private readonly Dictionary<char, TrieTree> Children;

        public bool End { get; set; }

        public TrieTree()
        {
            Children = new Dictionary<char, TrieTree>();
        }

        public void AddKey(string keyword)
        {
            if (String.IsNullOrEmpty(keyword))
            {
                return;
            }

            var cNode = this;

            foreach (var key in keyword)
            {
                if (cNode.Children.ContainsKey(key))
                {
                    cNode = cNode.Children[key];
                }
                else
                {
                    var node = new TrieTree();
                    cNode.Children.Add(key, node);
                    cNode = node;
                }
            }
            cNode.End = true;
        }


        public void Replace(ref string text)
        {
            for (var i = 0; i < text.Length; i++)
            {
                var cNode = this;
                var key = text[i];
                //碰到脏词的第一个词
                if (cNode.Children.ContainsKey(key))
                {
                    cNode = cNode.Children[key];
                    //查找是否包含脏词后面的词
                    var skip = 0;
                    for (var j = i + 1; j < text.Length; j++)
                    {
                        if (cNode.Children.ContainsKey(text[j]))
                        {
                            cNode = cNode.Children[text[j]];
                            skip = 0;
                        }
                        else
                        {
                            //允许略过过几个字符
                            skip++;
                            if (skip > 3)
                            {
                                break;
                            }
                        }
                        if (cNode.End)
                        {
                            var len = j + 1 - i;
                            text = text.Replace(text.Substring(i, len), string.Empty.PadLeft(len, '*'));
                            i += len;
                            break;
                        }
                    }
                }
            }
        }

    }

使用方法如下:

    class Program
    {
        static void Main(string[] args)
        {
            var trie = new TrieTree();
            var keywords = "我操,妓女,fuck".Split(',');
            foreach (var key in keywords)
            {
                trie.AddKey(key);
            }

            var text = @"我擦啊,尼玛,我操 你 妈,fuck you,你这个妓女,贱人。";
            trie.Replace(ref text);
            Console.WriteLine(text);
            Console.Read();
        }
    }

执行结果如下: