上图所示的角色是几个月前由Mikko Hyppönen发来的,他是一位以计算机病毒和计算机安全TED talks着称的计算机安全专家。关于SO,我只会发布它的图像,但你明白了。这显然不是你想要在你的网站上传播并吓跑游客的东西。
经过进一步检查,该字符似乎是一个泰语字母和超过87个变音符号的字母(甚至有限制?!)。这让我想到了安全性,本地化以及如何处理这种输入。我的搜索引导我在Stack上this question,然后在stripping diacritics上发表Michael Kaplan的博客文章。在其中,他演示了如何将字符串分解为其“基本”字符(为简洁起见,在此简化):
StringBuilder sb = new StringBuilder();
foreach (char c in "façade".Normalize(NormalizationForm.FormD))
{
if (char.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
sb.Append(c);
}
Response.Write(sb.ToString()); // facade
我可以看到这在某些情况下是如何有用的,但就用户输入而言,它将剥离所有变音符号。正如卡普兰指出的那样,删除一些语言中的变音符号可以完全改变单词的含义。这引出了一个问题:如何在用户输入/输出中允许一些变音符号,但排除其他极端情况,例如MikkoHyppönen的“超人”?
答案 0 :(得分:23)
是否有限制?!
本质上不是Unicode。在UAX-15中存在“流安全”格式的概念,其设置了30个组合器的限制......通常不保证Unicode字符串是流安全的,但这当然可以作为Unicode的标志。不打算标准化需要比这更长的字形簇的新字符。
30仍然是一个非常糟糕的。已知时间最长的自然语言字形集群是1个基数的西藏Hakṣhmalawarayaṁ加上8个组合器,所以现在归一化为NFD并且不允许连续超过8个组合器的任何序列是合理的。
如果您只关心常见的西欧语言,您可能会将其降低到2.因此可能会在这些语言之间妥协。
答案 1 :(得分:2)
我认为我找到了使用NormalizationForm.FormC
代替NormalizationForm.FormD
的解决方案。根据{{3}}:
[FormC]表示使用full标准化Unicode字符串 规范分解,然后用序列替换 他们的主要复合材料,如果可能的话。
我认为它意味着它将字符分解为基本形式,然后根据一组保持一致的规则重新组合它们。我认为这对于比较目的很有用,但在我的情况下它完美无缺。 ü
,é
和Ä
等字符会被准确地分解/重新组合,而虚假字符无法重新组合,因此保持其基本形式:
答案 2 :(得分:1)
Here's regex应该消灭所有zalgo,包括在正常情况下被绕过的zalgo'范围。
([\u0300–\u036F\u1AB0–\u1AFF\u1DC0–\u1DFF\u20D0–\u20FF\uFE20–\uFE2F\u0483-\u0486\u05C7\u0610-\u061A\u0656-\u065F\u0670\u06D6-\u06ED\u0711\u0730-\u073F\u0743-\u074A\u0F18-\u0F19\u0F35\u0F37\u0F72-\u0F73\u0F7A-\u0F81\u0F84\u0e00-\u0eff\uFC5E-\uFC62]{2,})
最难的是识别它们,一旦你做到了 - 有很多解决方案。
希望这可以节省你一些时间。