Unicode-строки в.Net с еврейскими буквами и цифрами
При попытке создать строку, содержащую букву иврита и цифру, происходит странное поведение. Цифра всегда будет отображаться слева от буквы. Например:
string A = "\u05E9"; //A Hebrew letter
string B = "23";
string AB = A + B;
textBlock1.Text = AB;
//Ouput bug - B is left to A.
Эта ошибка возникает только при использовании букв иврита и цифр. При исключении одного из них в уравнении ошибка не произойдет:
string A = "\u20AA"; //Some random Unicode.
string B = "23";
string AB = A + B;
textBlock1.Text = AB;
//Output OK.
string A = "\u05E9"; //A Hebrew letter.
string B = "HELLO";
string AB = A + B;
textBlock1.Text = AB;
//Output OK.
Я попытался поиграть со свойством FlowDirection, но это не помогло.
Обходное решение для правильного отображения текста в первом примере кода будет приветствоваться.
4 ответа
string A = "\u05E9"; //A Hebrew letter
string B = "23";
string AB = B + A; // !
textBlock1.Text = AB;
textBlock1.FlowDirection = FlowDirection.RightToLeft;
//Ouput Ok - A is left to B as intended.
Символы Unicode "RTL mark" (U+200F) и "LTR mark" (U+200E) были созданы именно для этой цели.
В вашем примере просто поместите метку LTR после ивритского символа, и цифры будут отображаться справа от ивритского символа, как вы пожелаете.
Таким образом, ваш код будет скорректирован следующим образом:
string A = "\u05E9"; //A Hebrew letter
string LTRMark = "\u200E";
string B = "23";
string AB = A + LTRMark + B;
Это из-за двунаправленных алгоритмов Unicode. Если я правильно понимаю, у символа юникода есть "идентификатор", который говорит, где он должен быть, когда он находится рядом с другим словом.
В этом случае \u05E9
говорит, что это должно быть слева. Даже если вы делаете:
var ab = string.Format("{0}{1}", a, b);
Вы все равно получите его слева. Тем не менее, если вы возьмете другой символ unicoded, например \u05D9
это будет добавлено справа, потому что этот персонаж не считается слева.
Это макет языка, и при его выводе компоновщик будет выводить его в соответствии с языковым макетом.
Это странное поведение имеет объяснение. Цифры с символами Unicode рассматриваются как часть строки Unicode. и так как иврит ланг читается справа налево, сценарий даст
string A = "\u05E9"; //A Hebrew letter
string B = "23";
string AB = A + B;
B
идет первым, а затем A
,
Второй сценарий:
string A = "\u20AA"; //Some random Unicode.
string B = "23";
string AB = A + B;
A
это какой-то юникод, не являющийся частью языка, который читается справа налево. поэтому вывод - первый A
с последующим B
,
теперь рассмотрим мой собственный сценарий
string A = "\u05E9";
string B = "\u05EA";
string AB = A + B;
и то и другое A
а также B
являются частью справа налево читать ланг, так AB
является B
с последующим A
, не A
с последующим B
,
Отредактировано, чтобы ответить на комментарий
принимая во внимание этот сценарий -
string A = "\u05E9"; //A Hebrew letter
string B = "23";
string AB = A + B;
Единственное решение, чтобы получить букву, за которой следуют цифры, это: string AB = B + A;
В общем, не решение, которое будет работать в целом. Итак, я думаю, вам нужно реализовать некоторые условия проверки и построить строку в соответствии с требованиями.