Вместо того, чтобы полагаться на внутреннюю реализацию, я принял несколько иной подход, который открыт для оптимизации, но дает достаточную основу для ответа на ваш вопрос.
Я просто загружаю UnicodeData.txt
, который является частью официального выпуска юникодной версии. Этот файл содержит для каждого 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++;
}
При запуске вы увидите символы, сильного типа и в каком положении они были найдены.
Это на самом деле довольно хорошее решение, я не знал, что существует перечисление символов в Юникоде. Еще лучше, это из официального источника. Благодаря! –