TextElement枚举器类Bug或(泰米尔语)Unicode Bug

时间:2013-09-24 12:05:47

标签: c# unicode .net-2.0 tamil

为什么TextElementEnumerator没有正确解析泰米尔语Unicode字符。

using System;
using System.Collections.Generic;
using System.Globalization;

namespace Glyphtest
{
    internal class Program
    {
        private static void Main()
        {
            const string unicodetxt1 = "ஊரவர் கெளவை";
            List<string> output = Syllabify(unicodetxt1);
            Console.WriteLine(output.Count);
            const string unicodetxt2 = "கௌவை";
            output = Syllabify(unicodetxt2);
            Console.WriteLine(output.Count);
        }

        public static List<string> Syllabify(string unicodetext)
        {
            if (string.IsNullOrEmpty(unicodetext)) return null;
            TextElementEnumerator enumerator = StringInfo.GetTextElementEnumerator(unicodetext);
            var data = new List<string>();
            while (enumerator.MoveNext())
                data.Add(enumerator.Current.ToString());
            return data;
        }
    }
}

以上代码示例处理Unicode字符

'கௌ' - &GT; 0x0bc8(க)+ 0xbcc(ௌ)。 (正确的表格)

'கௌ' - &gt; 0x0bc8(க)+ 0xbc6(ெ)+ 0xbb3(ள)(正确格式)

Text Element Enumerator班级的错误, 为什么它不能从字符串中正确枚举它。

即 கெளவை=&gt; 'கெள'+'''必须以正确的形式列举

கெளவை=&gt; 'கெ'+'''+'''不能以不正确的形式列举。

如果是这样,如何克服这个问题。

2 个答案:

答案 0 :(得分:1)

它不是Unicode字符或TextElementEnumerator类的错误, 具体到lanaguage(Tamil

任何Tamil consonants后跟可视字形的信件

例如─ க - \ u0b95 ெ - \ u0bc6 ள - \ u0bb3

形成泰米尔语字符'கெள',而它似乎与视觉字形的形成相似

க - \ u0b95 ௌ-\ u0bcc

及其正确的解决方案。 因此,在列举泰米尔语字符之前,我们已经取代了不规则的字符形成。

与泰米尔语法(ஔகாரக் குறுக்கம்)一样 视觉字形(ௌ)将作为单词的首字母。

这样。上面的代码应该被处理为

internal class Program
{
    private static void Main()
    {
        const string unicodetxt1 = "ஊரவர் கெளவை";
        List<string> output = Syllabify(unicodetxt1);
        Console.WriteLine(output.Count);
        const string unicodetxt2 = "கௌவை";
        output = Syllabify(unicodetxt2);
        Console.WriteLine(output.Count);
    }

    public static string CheckVisualGlyphPattern(string txt)
    {
        string[] data = txt.Split(new[] { ' ', '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries);
        string list = string.Empty;
        var rx = new Regex("^(.*?){1}(\u0bc6){1}(\u0bb3){1}");
        foreach (string s in data)
        {
            var matches = new List<Match>();
            string outputs = rx.Replace(s, match =>
            {
                matches.Add(match);
                return string.Format("{0}\u0bcc", match.Groups[1].Value);
            });
            list += string.Format("{0} ", outputs);
        }
        return list.Trim();
    }

    public static List<string> Syllabify(string unicodetext)
    {
        var processdata = CheckVisualGlyphPattern(unicodetext);
        if (string.IsNullOrEmpty(processdata)) return null;
        TextElementEnumerator enumerator = StringInfo.GetTextElementEnumerator(processdata);
        var data = new List<string>();
        while (enumerator.MoveNext())
            data.Add(enumerator.Current.ToString());
        return data;
    }
}

在枚举时产生适当的视觉字形。

答案 1 :(得分:0)

U + 0BB3ᴛᴀᴍɪʟʟᴇᴛᴛᴇʀʟʟᴀ有Grapheme_Cluster_Break = XX(其他)。这使得石墨烯簇<&lt; U + 0BC8 U + 0BC6&gt;&lt; U + 0BB3&gt;正确的,因为在Grapheme_Cluster_Break等于其他字符之前总是存在字形集群断点。

&lt; U + 0BC8 U + 0BCC&gt;因为U + 0BCC具有Grapheme_Cluster_Break = SpacingMark,并且在这些字符之前通常没有中断(例外是在文本的开头或者在控制字符之前),所以没有内部字形集群断点。

嗯,至少这是Unicode标准所说的(http://www.unicode.org/reports/tr29/#Grapheme_Cluster_Boundaries)。

现在,我不知道泰米尔人是如何工作的,所以请用一小撮盐来做些事。

U + 0BCC分解成&lt; U + 0BC6 U + 0BD7&gt;,意味着两个序列(&lt; U + 0BC8 U + 0BC6 U + 0BB3&gt;和&lt; U + 0BC8 U + 0BCC&gt;)不是规范等价的,因此,不需要字形集群分割来产生相同的结果。

当我用我的泰米尔人无知的眼睛看着它时,似乎U + 0BCCᴛᴀᴍɪʟᴀᴜʟᴇɴɢᴛʜᴍᴀʀᴋ和U + 0BB3ᴛᴀᴍɪʟʟᴇᴛᴛᴇʀʟʟᴀ看起来完全一样。但是,U + 0BCC是间距标记,但U + 0BB3不是。如果在输入中使用U + 0BCC而不是U + 0BB3,结果就是您所期望的。

坚持下去,我会说你使用的是错误的角色,但是,我根本不认识泰米尔语,所以我无法确定。