English 中文(简体)
如何将重音字符更改为非重音字符 [重复]
原标题:
  • 时间:2008-12-01 16:07:43
  •  标签:

我在Stackoverflow上找到了如何去除变音字符的答案,但是请问是否可能将变音字符更改为非变音字符?

哦..我在想.NET(如果不可能的话,其他的)

最佳回答

我对另一个问题的回答复制:

不需要创建自己的表,您可以将文本转换为规范化形式D,其中字符表示为基本字符加上变音符号(例如,"á"将被替换为"a"后面跟着一个组合的尖音符号)。然后,您可以剥离除ASCII字母以外的一切内容。

这些表仍然存在,但现在是Unicode标准中的表。

您也可以尝试NFKD而不是NFD,以捕捉更多情况。

参考文献:

问题回答

由于从未有人费心发布执行此操作的代码,这里提供一下:

    // p{Mn} or p{Non_Spacing_Mark}: 
    //   a character intended to be combined with another 
    //   character without taking up extra space 
    //   (e.g. accents, umlauts, etc.). 
    private readonly static Regex nonSpacingMarkRegex = 
        new Regex(@"p{Mn}", RegexOptions.Compiled);

    public static string RemoveDiacritics(string text)
    {
        if (text == null)
            return string.Empty;

        var normalizedText = 
            text.Normalize(NormalizationForm.FormD);

        return nonSpacingMarkRegex.Replace(normalizedText, string.Empty);
    }

注意:需要做这件事的一个重要原因是当你需要与一个只支持ASCII的第三方系统集成,但你的数据是Unicode时。这是很常见的情况。你基本上有两个选择:删除重音字符或尝试从带重音字符中删除重音,以尽可能保留原始输入的大部分内容。显然,这不是一个完美的解决方案,但它比仅删除ASCII 127以上的任何字符好80%以上。

重回思考一下为什么你想做这件事可能也值得。如果你试图消除你认为不重要的字符差异,你应该查看 Unicode 排序算法。这是在搜索或排序时忽略大小写或重音符号等字符差异的标准方式。

如果您打算展示修改后的文本,请考虑您的观众。您可以安全过滤的内容取决于当地敏感性。在美国英语中,“Igloo”=“igloo”,“resume”=“résumé”,但在土耳其语中,小写字母I为ı(无点),在法语中,cote表示引文,côté表示一侧,côte表示海岸。因此,分类语言决定了哪些差异是重要的。

如果去除变音符是您应用程序的正确解决方案,最安全的方法是制作您自己的表格,其中您明确添加要转换的字符。

一个通用的、自动化的方法可以使用Unicode分解来设计。使用该方法,您可以将带变音符号的字符分解为“组合字符”(变音符号)和它们结合的基本字符。过滤掉任何组合字符,您就可以得到“非变音符号”的字符。

自动化方法缺乏歧视性,但可能会产生一些意想不到的影响。我建议在代表性的文本集上进行大量测试。

举个简单例子:

去除字符串中的重音符号:

string newString = myDiacriticsString.Normalize(NormalizationForm.FormD);

我的网站从许多奇怪字符的外部来源输入数据。我编写了以下C#功能,使用正则表达式替换重音字符并剥离非美国键盘字符:

    using System.Text;
    using System.Text.RegularExpressions;

    internal static string SanitizeString(string source)
    {
        return Regex.Replace(source.Normalize(NormalizationForm.FormD), @"[^A-Za-z 0-9 .,? ""!@#$%^&*()-_=+;:<>/\|}{[]`~]*", string.Empty).Trim();    
    }

希望它能有所帮助。





相关问题
热门标签