9

我正在尝试从波兰语的 pangram 中删除变音符号。我正在使用 Michael Kaplan 的博客http://www.siao2.com/2007/05/14/2629747.aspx中的代码,但是没有成功。

考虑以下 pangram:“Pchnąć w tę łódź jeża lub ośm skrzyń fig.”。一切正常,但对于字母“ł”,我仍然得到“ł”。我想问题是“ł”表示为单个 unicode 字符,并且没有后续的 NonSpacingMark。

你知道我该如何修复它(不依赖某些字典中的自定义映射 - 我正在寻找某种 unicode 转换)?

4

7 回答 7

8

前段时间我遇到了这个解决方案,它似乎工作正常:

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

        return asciiEquivalents;
    }
于 2015-02-16T12:19:24.853 回答
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);
    }
}

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

于 2010-09-28T16:19:23.947 回答
3

文章中采用的方法是删除 Mark, Nonspacing 字符。由于您正确指出“ł”不是由两个字符组成(其中一个是标记,非空格),因此您看到的行为是预期的。

我不认为 Unicode 的结构可以让您完成完全自动化的重新映射(您引用的文章的作者得出了相同的结论)。

如果您只是对波兰语字符感兴趣,那么至少映射很小且定义明确(参见例如http://www.biega.com/special-char.html的底部)。对于一般情况,我认为不存在针对不由标准字符加上标记、非间距字符组成的字符的自动化解决方案。

于 2010-08-24T21:22:45.653 回答
2

它在Unicode 图表中,代码点 \u0142。向下滚动到描述“带有笔划的拉丁小写字母”,它没有列出分解。对波兰语一无所知,但一个字母通常有一个区别标记,使其成为自己的字母,而不是带有变音符号的基本字母。

于 2010-08-24T21:44:44.597 回答
2

您必须手动替换这些(就像 Latin-1 中的 ÆÐØÞßæðøþ 一样)。

其他人也遇到过同样的问题,因此 Unicode 通用语言环境数据存储库“同意添加一个音译器来去除重音,即使是重叠的重音也是如此。” (票#2884

于 2010-08-25T12:42:55.453 回答
1

有很多预先组合的字符没有有意义的分解。

(也有少数可以进行合理的分解,在大多数规范化形式中禁止这种分解,因为它会导致版本之间的差异,这将使它们不再真正规范化)。

ł 就是其中之一。IIRC 也不可能对不使用 ł 的字母进行文化中立的转录。我认为德国人倾向于将其转录为 w 而不是 l(或者可能是其他人这样做),这是有道理的(听起来也不太正确,但比 l 更接近)。

于 2010-08-25T00:15:17.160 回答
-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);
    }
于 2020-11-13T07:09:50.440 回答