如何在C#中找到字符串的第一个强方向性字符?

时间:2016-01-20 13:47:34

标签: c# .net unicode right-to-left cultureinfo

假设我得到的字符串可以包含从左到右和从右到左混合的内容,我想在其中找到第一个强方向性字符,如定义here

我认为我在this问题中找到了一个很好的起点,但我仍然无法弄清楚BiDi类别与强方向性特征的关系。是否有可能在C#中解决这个问题?

1 个答案:

答案 0 :(得分:1)

我没有依赖内部实现,而是采用了一种稍微不同的方法,这种方法可以进行优化,但提供了足够的基础来回答你的问题。

我只需下载UnicodeData.txt,这是unicode版本正式版的一部分。该文件包含每个unicodecharacter的数字和一些分号分隔的字段。典型的线条如下所示:

0041;LATIN CAPITAL LETTER A;Lu;0;L;;;;;N;;;;0061;

第五个字段包含Bidirectional Class Value

有了这些知识,天真的解析器会读取数据,然后用它检查一个演示字符串,如下所示:

// hold chars with their Bidi Class Value
var udb = new Dictionary<char, string>();

// download UnicodeData txt file
var cli = new WebClient();
var data = cli.DownloadData("http://www.unicode.org/Public/UNIDATA/UnicodeData.txt");
// parse
using (var ms = new MemoryStream(data))
{
    var sr = new StreamReader(ms, Encoding.UTF8);
    var line = sr.ReadLine();
    while (line != null)
    {
        var fields = line.Split(';');

        int uc = int.Parse(fields[0], NumberStyles.HexNumber);
        // above 0xffff we're lost
        if (uc > 0xffff) break;

        var ch = (char) uc;
        var bca = fields[4];

        udb.Add(ch, bca);

        line = sr.ReadLine();
    }
}

// test string
var s = "123A\xfb1d\x0620";

Console.WriteLine(s);
var pos = 0;
foreach(var c in s)
{

    var bcv = udb[c]; // for a char get the Bidi Class Value
    if (bcv == "L" || bcv == "R" || bcv == "AL")
    {
        Console.WriteLine(
            "{0} - {1} : {2} [{3}]", 
            c, 
            pos, 
            CharUnicodeInfo.GetUnicodeCategory(c), 
            bcv); 
    }
    pos++;
}

运行时,您会看到强类型的字符以及找到它们的位置。