Арабские формы представления поддержки B в c # - PullRequest
5 голосов
/ 21 сентября 2010

Я пытался преобразовать файл из utf-8 в кодировку Arabic-1265 , используя API-интерфейсы кодирования в C #, но я столкнулся со странной проблемой, заключающейся в том, что некоторые символы преобразовываются неправильно, например, "لا"в следующем утверждении «ﻣﺣﻣد ﺻﻼ ح عادل» оно выглядит как «ﻣﺣﻣد ﺻ? ح عادل».Некоторые из моих друзей сказали мне, что это потому, что эти символы взяты из арабских презентационных форм B. Я создаю файл с помощью notepad ++ и сохраняю его как utf-8.

Вот код, который я использую

    StreamReader sr = new StreamReader(@"C:\utf-8.txt", Encoding.UTF8);
    string str = sr.ReadLine();
    StreamWriter sw = new StreamWriter(@"C:\windows-1256.txt", false, Encoding.GetEncoding("windows-1256"));
    sw.Write(str);
    sw.Flush();
    sw.Close();

Но я не знаю, как правильно конвертировать файл с помощью этой формы представления в C #.

Ответы [ 3 ]

5 голосов
/ 21 сентября 2010

Да, ваша строка содержит много лигатур, которые не могут быть представлены в кодовой странице 1256.Вам придется разложить строку перед ее записью.Как это:

  str = str.Normalize(NormalizationForm.FormKD);
  st.Write(str);
3 голосов
/ 21 сентября 2010

Чтобы дать более общий ответ:

  • Кодировка Windows-1256 - это устаревшая 8-разрядная кодировка символов . В нем всего 256 символов, из которых только 60 арабских букв.

  • Уникод имеет гораздо более широкий диапазон символов. В частности, он содержит:

    • «нормальные» арабские символы от U + 0600 до U + 06FF. Предполагается, что они будут использоваться для обычного арабского текста, включая текст, написанный на других языках, использующих арабский алфавит, например на фарси. Например, «لا» - это U + 0644 (ل), за которым следует U + 0627 (ا).

    • символы «Форма представления», от U + FB50 до U + FDFF («Формы представления-A») и от U + FE70 до U + FEFF («Формы представления-B»). Они не предназначены для представления текста на арабском языке. Они в первую очередь предназначены для совместимости, особенно с форматами файлов шрифтов, которые требуют отдельных кодовых точек для каждой разной лигированной формы каждого сочетания символов и лигированных символов. Лигатура «لا» представлена ​​одной кодовой точкой (U + FEFB), несмотря на то, что она состоит из двух символов.

  • При кодировании в Windows-1256 кодировка .NET для Windows-1256 автоматически преобразует символы из блока форм представления в «обычный текст» , поскольку у него нет другого выбора (кроме, конечно, чтобы превратить все это в вопросительные знаки). По понятным причинам он может делать это только с символами, которые на самом деле имеют «эквивалент».

  • При декодировании из Windows-1256 кодировка .NET для Windows-1256 всегда генерирует символы из блока «обычный текст».

Как мы обнаружили, ваш входной файл содержит символы, которые не могут быть представлены в Windows-1256 . Такие символы превратятся в вопросительные знаки (?). Кроме того, те символы формы представления, которые do имеют эквивалент обычного текста, изменят свое поведение при лигировании, потому что именно так поступает обычный арабский текст.

0 голосов
/ 21 сентября 2010

Прежде всего, вы указали два символа , а не из блока арабских форм представления. Это \x0644 и \x0627 из стандартного арабского блока. Тем не менее, просто чтобы убедиться, что я попробовал символ \xFEFB, который равен «эквивалентным» (не эквивалентным, но вы знаете) символом для لا из блока Presentation Forms, и он отлично работает даже для этого .

Во-вторых, я предполагаю, что вы имеете в виду кодировку Windows-1256 , которая предназначена для устаревшего 8-битного арабского текста.

Итак, я попробовал следующее:

var input = "لا";
var encoding = Encoding.GetEncoding("windows-1256");
var result = encoding.GetBytes(input);
Console.WriteLine(string.Join(", ", result));

Я получаю вывод 225, 199. Итак, давайте попробуем повернуть его обратно:

var bytes = new byte[] { 225, 199 };
var result2 = encoding.GetString(bytes);
Console.WriteLine(result2);

Достаточно справедливо, Консоль не отображает результат правильно - но окно Watch в отладчике говорит мне, что ответ правильный (он говорит «لا»). Я также могу скопировать вывод из консоли, и он правильный в буфере обмена.

Поэтому кодировка Windows-1256 работает просто отлично, и неясно, в чем ваша проблема.

Моя рекомендация:

  • Напишите небольшой фрагмент кода, который показывает проблему.

  • Опубликовать новый вопрос с этим фрагментом кода.

  • В этом вопросе опишите точно, какой результат вы получите, и какой результат вы ожидали вместо этого.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...