【问题标题】:Replace Bad words using Regex使用正则表达式替换坏词
【发布时间】:2026-01-16 04:45:01
【问题描述】:

我正在尝试创建一个坏词过滤器方法,我可以在每次插入和更新之前调用该方法来检查字符串中是否存在任何坏词并替换为“[Censored]”。

我有一个包含坏词列表的 SQL 表,我想将它们带回来并将它们添加到列表或字符串数​​组中,并检查已传入的文本字符串以及是否发现任何坏词替换它们并返回过滤后的字符串。

我为此使用 C#。

【问题讨论】:

  • 在不保留未经审查字符串的副本的情况下更新/插入审查字符串可能不是一个好主意。您很可能必须在多次迭代中调整您的单词表和替换策略,直到它“足够正确”并且不应该在此期间冒险破坏您的数据
  • 给你投票只是因为他们称他们为“坏话”。

标签: c# .net regex


【解决方案1】:

在不考虑单词边界的情况下进行字符串替换之前,请参阅此“clbuttic”(或针对您的情况 cl[Censored]ic)文章:

http://www.codinghorror.com/blog/2008/10/obscenity-filters-bad-idea-or-incredibly-intercoursing-bad-idea.html

更新

显然不是万无一失(见上面的文章 - 这种方法很容易绕过或产生误报......)或优化(正则表达式应该被缓存和编译),但以下将过滤掉整个单词(不"clbuttics") 和单词的简单复数形式:

const string CensoredText = "[Censored]";
const string PatternTemplate = @"\b({0})(s?)\b";
const RegexOptions Options = RegexOptions.IgnoreCase;

string[] badWords = new[] { "cranberrying", "chuffing", "ass" };

IEnumerable<Regex> badWordMatchers = badWords.
    Select(x => new Regex(string.Format(PatternTemplate, x), Options));

string input = "I've had no cranberrying sleep for chuffing chuffings days -
    the next door neighbour is playing classical music at full tilt!";

string output = badWordMatchers.
   Aggregate(input, (current, matcher) => matcher.Replace(current, CensoredText));

Console.WriteLine(output);

给出输出:

我已经 [Censored] [Censored] 天没有 [Censored] 睡眠 - 隔壁邻居正在全力播放古典音乐!

请注意,“classical”不会变成“cl[Censored]ical”,因为整个单词都与正则表达式匹配。

更新 2

为了演示这种(以及一般的基本字符串\模式匹配技术)如何被轻松颠覆,请参见以下字符串:

“我已经好几天没睡觉了——隔壁的邻居正在全速播放古典音乐!”

我已将“i”替换为土耳其小写字母“ı”。看起来还是很反感!

【讨论】:

  • 好的背景文章。可能会将其作为评论而不是答案,因为它并没有真正回答问题。
  • @Robin 我会在地狱中燃烧,但我提供了一个例子。
  • +1,虽然这是一个很难/不可能解决的问题。 (由于使用的字体,我已经看到充满名称 CLINT 的拱廊!)我仍然宁愿看到一堆 S[Censored]horpe 错误,而不是充满淫秽内容的儿童浏览器。
  • @Robin 上述方法会给出我认为更合适的“Scunthorpe”。孩子天生好奇。
【解决方案2】:

虽然我是 Regex 的忠实粉丝,但我认为它在这里对你没有帮助。您应该将您的坏词提取到一个字符串列表或字符串数​​组中,并在您的传入消息中使用System.String.Replace

也许更好,使用System.String.Split.Join 方法:

string mayContainBadWords = "... bla bla ...";
string[] badWords = new string[]{"bad", "worse", "worst"};

string[] temp = string.Split(badWords, StringSplitOptions.RemoveEmptyEntries);
string cleanString = string.Join("[Censored]", temp);

在示例中,mayContainBadWords 是您要检查的字符串; badWords 是一个字符串数组,你从你的坏词 sql 表中加载,cleanString 是你的结果。

【讨论】:

  • 这会将羽毛球变成 [审查] 明顿
  • 没错! :D - 但说真的,这只是一个示例,而不是解决方案......我在这里看到没有批准使用正则表达式。
  • 它把“坏”变成“”但不是“[审查]”
【解决方案3】:

你可以使用 string.replace() 方法或 RegEx 类

【讨论】:

    【解决方案4】:

    还有一篇很好的文章可以找到here

    稍加一点html解析技巧,就可以得到来自noswear的一大堆脏话列表

    【讨论】: