如何在 .Net 中检查 Unicode 字符是否有变音符号?

7
我正在开发自动语言检测的启发式算法,想知道给定的字母是否有变音符号(比如“Ðàäèî Êóëüòóðà”——所有字母都有变音符号)。如果可能的话,最好能够获取变音符号的类型。我翻阅了UnicodeCategory枚举,但没有找到任何可以帮助我的东西。

字母eth(Ð)没有变音符号。在Unicode中,它是一个基本字符;该笔画不被视为变音符号。因此,您可能希望重新制定您的目标(并可能解释它将解决什么具体问题,因为可能有更好的方法)。 - Jukka K. Korpela
2
分解是你最不想做的事情。特定字母与特定变音符号的组合是语言选择器的强有力工具。只需提前建立频率表即可。但是,有很多语言几乎不使用变音符号。例如,你将无法区分英语、荷兰语和意大利语。你需要一个词典来使其真正发挥作用。存储最常见的100个单词将大有裨益。 - Hans Passant
2个回答

16

一种可能的方法是将其规范化为以字母及其音标写成多个代码点的形式。然后检查是否有一个字母后跟着音标。

参考如何在 .NET 中删除变音符号 (音调)?,您可以使用Normalize(NormalizationForm.FormD)进行规范化,并使用UnicodeCategory.NonSpacingMark检查变音符号。

bool IsLetterWithDiacritics(char c)
{
    var s = c.ToString().Normalize(NormalizationForm.FormD);
    return (s.Length > 1)  &&
           char.IsLetter(s[0]) &&
           s.Skip(1).All(c2 => CharUnicodeInfo.GetUnicodeCategory(c2) == UnicodeCategory.NonSpacingMark);
}

3
如果您需要进行真/假检查,您可以将其规范化为FormD或其他形式,然后只需检查字符串是否比原始字符串长即可。 - Joakim Johansson
1
@JoakimJohansson 我不会感到惊讶,如果还有其他在FormD中分解的字形,但它们不是重音字母。但我也不知道我的想法在那些上会表现得如何。 - CodesInChaos
2
@JoakimJohansson 你的算法认为带有变音符号的字符中有一个大类是韩文汉字。它们由几个部分组成,可以被分解,但不是变音符号。一些例子包括:。然后还有数学符号,例如:。最后还有一些我完全不知道的字符: - CodesInChaos
变音符号只是非间距组合字符的一个子集。例如,Unicode 字符 "\u0CBF"UnicodeCategory.NonSpacingMark,但它不是一个变音符号。 - Paolo Moretti
@PaoloMoretti 输入必须是单个代码点的分解,且分解中的第一个代码点必须是字母。因此,您的示例不会导致算法失败。我不确定是否存在任何误报情况。在阿拉伯文中有一些奇怪的情况,但我不知道它们是否是变音符号。但如果您知道更好的算法,我愿意听取建议。 - CodesInChaos

0

试试这个:


  public bool CheckIsStringContainDiacriticsCharacter(string text)
        {
            bool IsDiacriticsCharacter = false;

            var normalizedString = text.Normalize(NormalizationForm.FormD);
            var stringBuilder = new StringBuilder();
            foreach (var c in normalizedString)
            {
                var unicodeCategory = CharUnicodeInfo.GetUnicodeCategory(c);
                if (unicodeCategory != UnicodeCategory.NonSpacingMark)
                {
                    stringBuilder.Append(c);
                }
                else
                {
                    IsDiacriticsCharacter = true;
                    break;
                }
            }
      
            return IsDiacriticsCharacter;
        }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接