Обратить строку с акцентом?
Итак, я увидел Jon skeet видео и был пример кода:
Должна была быть проблема с é
- после реверсирования, но я думаю, что она терпит неудачу на .net2 (IMHO), в любом случае это сработало для меня, и я видел правильную строку в обратном порядке.
char[] a="Les Misérables".ToCharArray();
Array.Reverse(a);
string n= new string(a);
Console.WriteLine (n); //selbarésiM seL
Но я понял:
На иврите есть "Алеф" char: א
и я могу добавить знаки препинания как: אֳ
(который, я считаю, состоит из 2 символов, но пока отображается как один.)
Но посмотрим, что получится:
char[] a="Les Misאֳrables".ToCharArray();
Array.Reverse(a);
string n= new string(a);
Console.WriteLine (n); //selbarֳאsiM seL
Был раскол...
Я могу понять, почему это происходит:
Console.WriteLine ("אֳ".Length); //2
Так что мне было интересно, если обходной путь для такого рода проблем в С# (или мне нужно создать собственный механизм...)
Ответы
Ответ 1
Проблема заключается в том, что Array.Reverse
не знает, что определенные последовательности значений char
могут объединяться, чтобы сформировать один символ или "grapheme" и, следовательно, не должны быть отменены. Вы должны использовать что-то, что понимает Unicode, объединяющее последовательности символов, например TextElementEnumerator:
// using System.Globalization;
TextElementEnumerator enumerator =
StringInfo.GetTextElementEnumerator("Les Misאֳrables");
List<string> elements = new List<string>();
while (enumerator.MoveNext())
elements.Add(enumerator.GetTextElement());
elements.Reverse();
string reversed = string.Concat(elements); // selbarאֳsiM seL
Ответ 2
Если вы сделали расширение
public static IEnumerable<string> ToTextElements(this string source)
{
var e = StringInfo.GetTextElementEnumerator(source)
while (e.MoveNext())
{
yield return e.GetTextElement();
}
}
вы могли бы сделать,
const string a = "AnyStringYouLike";
var aReversed = string.Concat(a.ToTextElements().Reverse());