去除波兰语中的变音符号

9
我正在尝试从波兰句子中删除变音符号。我使用的是Michael Kaplan博客中的代码http://www.siao2.com/2007/05/14/2629747.aspx,但是没有成功。
考虑以下句子:"Pchnąć w tę łódź jeża lub ośm skrzyń fig."。除了字母"ł"之外,一切正常,我仍然得到"ł"。我猜问题在于"ł"被表示为单个Unicode字符,并且没有后续的NonSpacingMark。
您有任何想法如何解决这个问题(不依赖于某些字典中的自定义映射 - 我正在寻找某种Unicode转换)?
9个回答

8

前段时间我发现了这个解决方案,看起来效果不错:

    public static string RemoveDiacritics(this string s)
    {
        string asciiEquivalents = Encoding.ASCII.GetString(
                     Encoding.GetEncoding("Cyrillic").GetBytes(s)
                 );

        return asciiEquivalents;
    }

系统参数异常:不支持编码名称“Cyrillic”。我还需要转换法语,但我认为这样做也行不通 :( 那德语呢? - Pawel Cioch

4
这是我对波兰停用词表的快速实现,同时对波兰变音符号进行了规范化处理。
    class StopList
{
    private HashSet<String> set = new HashSet<String>();

    public void add(String word)
    {
        word = word.trim().toLowerCase();
        word = normalize(word);
        set.add(word);

    }

    public boolean contains(final String string)
    {
        return set.contains(string) || set.contains(normalize(string));
    }

    private char normalizeChar(final char c)
    {
        switch ( c)
        {
            case 'ą':
                return 'a';
            case 'ć':
                return 'c';
            case 'ę':
                return 'e';
            case 'ł':
                return 'l';
            case 'ń':
                return 'n';
            case 'ó':
                return 'o';
            case 'ś':
                return 's';
            case 'ż':
            case 'ź':
                return 'z';
        }
        return c;
    }

    private String normalize(final String word)
    {
        if (word == null || "".equals(word))
        {
            return word;
        }
        char[] charArray = word.toCharArray();
        char[] normalizedArray = new char[charArray.length];
        for (int i = 0; i < normalizedArray.length; i++)
        {
            normalizedArray[i] = normalizeChar(charArray[i]);
        }
        return new String(normalizedArray);
    }
}

我在网上找不到其他解决方案。所以也许对某些人有帮助(?)


除了 ł 之外,所有这些字符都只有 变音符号(至少有 ogonek、acute 和 dot),可以使用 Normalize 轻松标准化。我建议将这两种方法结合起来使用。 - BalusC
Normalize是.NET库吗?抱歉...那是我Java代码的片段 :) 当我写"Net"时,我在想互联网,而不是".NET"。 - Michal_R
手动输入始终是一种选择,但我需要编写所有的组合吗?法语、德语、波兰语等等? - Pawel Cioch

3
本文的方法是删除Mark、非间隔字符。正如你正确指出的那样,“ł”并不由两个字符(其中一个是Mark、非间隔)组成,所以你看到的行为是可以预期的。
我认为Unicode的结构不允许你实现完全自动的重新映射(你参考的文章的作者得出了相同的结论)。
如果你只对波兰字符感兴趣,至少映射是小而明确定义的(例如,请参见http://www.biega.com/special-char.html底部)。对于一般情况,我认为不存在自动解决标准字符加上Mark、非间隔字符以外字符的方案。

2
它在Unicode图表的代码点为\u0142。向下滚动到描述部分,“带划线的拉丁小写字母”,没有分解列表。我不知道波兰语,但一个字母通常会有一个区别标记,使其成为一种独特的字母,而不是带有附加符号的基本字母。

2

你需要手动替换这些字符(就像在Latin-1中的ÆÐØÞßæðøþ一样)。

其他人也遇到了同样的问题,因此Unicode Common Locale Data Repository已经“同意添加一个转换器来去除重叠重音符号”。(票号#2884)


1
public static string ReplacePolishSigns(this string input) 
        => input.Replace("ą", "a")
            .Replace("ć", "c")
            .Replace("ę", "e")
            .Replace("ł", "l")
            .Replace("ń", "n")
            .Replace("ó", "o")
            .Replace("ś", "s")
            .Replace("ż", "z")
            .Replace("ź", "z");    

1

有一些预组合字符没有任何有意义的分解。

(也有一些可能有合理分解但在大多数规范化形式中被禁止分解,因为这会导致版本之间的差异,使它们不再是规范化)。

ł 就是其中之一。如果我没记错的话,对于不使用 ł 的字母表,很难给出一个文化中立的转录。我认为德国人倾向于将其转录为 w 而不是 l(或者可能是其他人),这是有道理的(虽然它的发音也不完全正确,但比 l 更接近)。


0

提出它。完美运作。

private static Dictionary<string, string> NormalizeTable()
{
    return new Dictionary<string, string>()
    {
        {"ą", "a"},
        {"ć", "c"},
        {"ę", "e"},
        {"ł", "l"},
        {"ń", "n"},
        {"ó", "o"},
        {"ś", "s"},
        {"ź", "z"},
        {"ż", "z"},
    };
}

public static string Normalize(string original)
{
    if (original == null) return null;
    var lower = original.ToLower();
    var dictionary = NormalizeTable();
    foreach (var (key, value) in dictionary)
    {
        lower = lower.Replace(key, value);
    }
    return lower;
}

-1

我找到了解决方案,它也处理了 'ł'。

string RemoveDiacritics(string text)
    {
        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);
            }
        }

        return stringBuilder.ToString().Normalize(NormalizationForm.FormC);
    }

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