Regex.IsMatch返回false

时间:2015-03-16 11:02:58

标签: c# regex

我有一个应用程序,我的用户可以写评论。 但我希望过滤侮辱特殊字符。

string comment = "Ðick"; // With special "Ð".

comment = Regex.Replace(comment, @"[^a-z0-9 ]", "[a-z]"); // Replace special char by "[a-z]"
Regex regex = new Regex(@""+comment +""); // @"[a-z]ick"

return (regex.IsMatch("dick")) ? true : false;

当注释只是“Ðick”时,该函数返回true,但如果注释为“Ðickwith another word”,则该函数返回false。为什么呢?

1 个答案:

答案 0 :(得分:2)

你要做的事情往往是通过Canonical分解加上剥离"组合变音符号"来完成的。您无法使用纯正则表达式执行此操作...即使只有少量C#,您也必须手动为某些字符执行此操作(例如ÐDØO)。对于其他一些角色,您可以使用更多"自动化"使用è的方式(例如estring.Normalize),例如:

string comment = "Ðè";

// Here we split (è) to U+0065 (e) U+0300 (̀)
string commentNormalized = comment.Normalize(NormalizationForm.FormD);

// Here we remove all the UnicodeCategory.NonSpacingMark
// that are the diacritics like U+0300 (̀)
// and rebuild the string. This line can be speedup a little, but
// it would be longer to write :-)
string comment2 = new string(commentNormalized.Where(x => char.GetUnicodeCategory(x) != UnicodeCategory.NonSpacingMark).ToArray());

现在comment2"Ðe"

这是因为è有一个" Canonical分解" U+0065 (e) U+0300 (̀),因此您可以发现è是"类似的"至e,而对于Ð它是" Canonical分解"仍然是U+00D0 (Ð)所以相同的角色。

你要做的事情是徒劳的:当你禁用一个角色时,用户会找到另一个类似的"你听说过Leet吗? D1ck1而不是i)比你的话更好吗? : - )

通常情况下,拥有一个包含DorkÐork的禁止字词"的字典通常会更好,并且当您找到"的新排列时,通常会更好。进攻"单词,你只需添加它。人类的幻想是无限的...所以你的字典必须是:-)但是一次一个字。