public static string RemoveAccents(string input)
{
return new string(input
.Normalize(System.Text.NormalizationForm.FormD)
.ToCharArray()
.Where(c => CharUnicodeInfo.GetUnicodeCategory(c) != UnicodeCategory.NonSpacingMark)
.ToArray());
// the normalization to FormD splits accented letters in letters+accents
// the rest removes those accents (and other non-spacing characters)
// and creates a new string from the remaining chars
}
或者让“高度安全”的ROT13编码与重音一起工作:
string Rot13(string input)
{
var v = input.Normalize(NormalizationForm.FormD)
.Select(c => {
if ((c>='a' && c<='m') || (c>='A' && c<='M'))
return (char)(c+13);
if ((c>='n' && c<='z') || (c>='N' && c<='Z'))
return (char)(c-13);
return c;
});
return new String(v.ToArray()).Normalize(NormalizationForm.FormC);
}
这将把“Crème brälée”转换为“Per zr oeyr”(当然反之亦然),首先将“character with accent”代码点拆分为单独的“character”和“accent”代码点(FormD),然后只对字母执行ROT13转换,然后尝试重新组合它们(FormC)。
4条答案
按热度按时间yrdbyhpb1#
格式C和格式D之间的一个区别是如何表示带重音的字母:表单C使用单个带重音字母的代码点,而表单D将其分成字母和重音。
例如,“à”可以是代码点224(“拉丁小写字母A带抑音符”),也可以是代码点97(“拉丁小写字母A”)后跟代码点786(“组合抑音符”)。逐个字符比较会发现它们是不同的。
一个副作用是,这使得创建“删除重音符号”方法变得容易。
或者让“高度安全”的ROT13编码与重音一起工作:
这将把“Crème brälée”转换为“Per zr oeyr”(当然反之亦然),首先将“character with accent”代码点拆分为单独的“character”和“accent”代码点(FormD),然后只对字母执行ROT13转换,然后尝试重新组合它们(FormC)。
2skhul332#
它确保可以比较unicode字符串是否相等(即使它们使用不同的unicode编码)。
摘自Unicode标准附录#15:
基本上,Unicode规范化算法将所有组合标记按指定顺序放置,并使用分解和组合规则将每个字符串转换为Unicode规范化形式之一。然后,对转换后的字符串进行二进制比较,以确定是否等效。
c6ubokkw3#
在Unicode中,(组合)字符可以具有唯一的代码点,也可以具有由基本字符及其重音组成的代码点序列。
Wikipedia列出越南语(U+1EBF)及其分解序列U+0065(e)U+0302(抑扬重音)U+0301(锐重音)作为例子。
string.normalize()在4种范式之间转换一个可以用Unicode编码的字符串。
8cdiaqws4#
这个链接有一个很好的解释:
http://unicode.org/reports/tr15/#Norm_Forms
据我推测,这样您就可以比较两个unicode字符串是否相等。