C# 如何删除字符串上的重音符号?

C# 如何删除字符串上的重音符号?,c#,.net,C#,.net,可能重复: 我有以下字符串 áéíóú 我需要把它转换成 aeiou 我怎样才能做到呢?(我不需要比较,我需要保存新字符串) 不是复制品。这里接受的答案没有任何解释,这就是我“重新打开”它的原因。publicstringremovediacritics(字符串输入) { 字符串stFormD=input.Normalize(NormalizationForm.FormD); int len=标准长度; StringBuilder sb=新的StringBuilder(); 对于(int

可能重复:

我有以下字符串

áéíóú
我需要把它转换成

aeiou
我怎样才能做到呢?(我不需要比较,我需要保存新字符串)


不是复制品。这里接受的答案没有任何解释,这就是我“重新打开”它的原因。

publicstringremovediacritics(字符串输入)
{
字符串stFormD=input.Normalize(NormalizationForm.FormD);
int len=标准长度;
StringBuilder sb=新的StringBuilder();
对于(int i=0;i
这取决于需求。对于大多数使用,然后归一化为NFD,然后过滤掉所有组合字符即可。在某些情况下,标准化为NFKD更合适(如果您还想消除字符之间的一些进一步区别)

其他一些区别将不会被这一点抓住,特别是笔划拉丁字符。对于某些人来说,也没有明确的非语言环境特定的方式(应该被视为等同于l或w吗?),因此您可能需要定制超出此范围的内容

也有一些情况下,NFD和NFKD的工作方式与预期的不一样,以保证Unicode版本之间的一致性

因此:

public static IEnumerable<char> RemoveDiacriticsEnum(string src, bool compatNorm, Func<char, char> customFolding)
{
    foreach(char c in src.Normalize(compatNorm ? NormalizationForm.FormKD : NormalizationForm.FormD))
    switch(CharUnicodeInfo.GetUnicodeCategory(c))
    {
      case UnicodeCategory.NonSpacingMark:
      case UnicodeCategory.SpacingCombiningMark:
      case UnicodeCategory.EnclosingMark:
        //do nothing
        break;
      default:
        yield return customFolding(c);
        break;
    }
}
public static IEnumerable<char> RemoveDiacriticsEnum(string src, bool compatNorm)
{
  return RemoveDiacritics(src, compatNorm, c => c);
}
public static string RemoveDiacritics(string src, bool compatNorm, Func<char, char> customFolding)
{
  StringBuilder sb = new StringBuilder();
  foreach(char c in RemoveDiacriticsEnum(src, compatNorm, customFolding))
    sb.Append(c);
  return sb.ToString();
}
public static string RemoveDiacritics(string src, bool compatNorm)
{
  return RemoveDiacritics(src, compatNorm, c => c);
}

在这种情况下,与上述方法结合使用可以去除笔划,以及可分解的变音符号。

为什么允许间隔组合标记和封闭标记?正如Karaszi在上文中所述,这是唯一一个可以做到这一点的例子。Bruno没有指定确切的要求。@cichy字符串没有规范化方法@熵是的,是的链接到它上面的Mono文档。很好的解决方案,也适用于阿拉伯语发音和其他特殊字符。有一些语法问题,你能解决吗?你的答案很有效,很有启发性。谢谢。没错,你是布鲁诺,有点错了,因为你写的是直接的回复,而不是从代码编辑器中复制。现在应该是正确的。+1它似乎有效,但我不明白。你能解释一下定制折叠吗?@bum这是为了抓住基本方法无法解决的情况。在给出的示例中,
c=>c
lambda只是忽略了这个问题,而
NormaliseLWithStroke
在不处理任何其他情况的情况下从stroked L中删除笔划。如果你永远不会使用它,你可以替换
yield-return-customFolding(c)仅<代码>收益率c并获得性能提升。另一方面,就如何处理韩国语韩语而言,恢复NFC的正常化可能是个好主意。你有没有可能把这个答案转移到被引用的问题上?该死,想取消我的重新开放-这肯定是重复的@布鲁诺姆如果你不喜欢这个答案,最好是悬赏,然后再问一个傻瓜
public static IEnumerable<char> RemoveDiacriticsEnum(string src, bool compatNorm, Func<char, char> customFolding)
{
    foreach(char c in src.Normalize(compatNorm ? NormalizationForm.FormKD : NormalizationForm.FormD))
    switch(CharUnicodeInfo.GetUnicodeCategory(c))
    {
      case UnicodeCategory.NonSpacingMark:
      case UnicodeCategory.SpacingCombiningMark:
      case UnicodeCategory.EnclosingMark:
        //do nothing
        break;
      default:
        yield return customFolding(c);
        break;
    }
}
public static IEnumerable<char> RemoveDiacriticsEnum(string src, bool compatNorm)
{
  return RemoveDiacritics(src, compatNorm, c => c);
}
public static string RemoveDiacritics(string src, bool compatNorm, Func<char, char> customFolding)
{
  StringBuilder sb = new StringBuilder();
  foreach(char c in RemoveDiacriticsEnum(src, compatNorm, customFolding))
    sb.Append(c);
  return sb.ToString();
}
public static string RemoveDiacritics(string src, bool compatNorm)
{
  return RemoveDiacritics(src, compatNorm, c => c);
}
private static char NormaliseLWithStroke(char c)
{
  switch(c)
  {
     case 'ł':
       return 'l';
     case 'Ł':
       return 'L';
     default:
       return c;
  }
}