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

时间:2010-09-22 13:02:20

标签: c# .net

  

可能重复:
  How do I remove diacritics (accents) from a string in .NET?

我有以下字符串

áéíóú

我需要将其转换为

aeiou

我怎样才能实现它? (我不需要比较,我需要保存新字符串)


不是How do I remove diacritics (accents) from a string in .NET?的副本。那里接受的答案没有解释任何事情,这就是为什么我“重新开启”它。

2 个答案:

答案 0 :(得分:23)

这取决于要求。对于大多数用途,然后归一化为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);
}

这里我们对上面提到的问题情况进行了默认,只是忽略了它们。我们还从生成字符枚举中拆分构建字符串,因此在不需要对结果进行字符串操作的情况下我们不必浪费(比如说我们要将字符写入下一个输出,或者做一些其他字符-by-char操纵)。

我们想要将ł和Ł转换为l和L的一些示例,但没有其他专门的问题可以使用:

private static char NormaliseLWithStroke(char c)
{
  switch(c)
  {
     case 'ł':
       return 'l';
     case 'Ł':
       return 'L';
     default:
       return c;
  }
}

在这种情况下,使用上述方法将结合使用可分解的变音符号来删除笔画。

答案 1 :(得分:15)

public string RemoveDiacritics(string input)
{
    string stFormD = input.Normalize(NormalizationForm.FormD);
    int len = stFormD.Length;
    StringBuilder sb = new StringBuilder();
    for (int i = 0; i < len; i++)
    {
        System.Globalization.UnicodeCategory uc = System.Globalization.CharUnicodeInfo.GetUnicodeCategory(stFormD[i]);
        if (uc != System.Globalization.UnicodeCategory.NonSpacingMark)
        {
            sb.Append(stFormD[i]);
        }
    }
    return (sb.ToString().Normalize(NormalizationForm.FormC));
}