2013-02-22 6 views
24

Так что я увидел Джон тарелочек video и был пример кода:Обратить строку с акцентами?

Там должны быть проблема с é - после реверсирования, но я предполагаю, что это не будет работать на .net2 (ИМХО), в любом случае это сделало работу я и я видели правильную обратную строку.

char[] a="Les Misérables".ToCharArray(); 
Array.Reverse(a); 
string n= new string(a); 
Console.WriteLine (n); //selbarésiM seL 

Но я взял его дальше:

На иврите есть «Алеф» символ: א

и я могу добавить знаки препинания, например: אֳ (который я считаю, состоит из 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 

Так мне было интересно, если есть обходной путь для такого рода проблемы в C# (или я должен построить свой механизм ....)

+4

[TextElementEnumerator] (HTTP: //msdn.microsoft.com/en-us/library/system.globalization.textelementenumerator.aspx) может быть здесь полезен. –

+0

Итак, 'א' - это два' chars'? – Jodrell

+0

Вы должны добавить это как ответ Майкл. Просто писал, что в .NET нет такой вещи ... Хорошая работа. –

ответ

35

Проблема заключается в том, что Array.Reverse не знает, что определенные последовательности значений char могут объединяться, чтобы сформировать один символ или «графем» и, следовательно, не должны быть отменены. Вы должны использовать то, что понимает 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 
+0

Просто, чтобы уточнить, является ли это 'ToCharArray()', который не знает этих последовательностей, или 'Array.Reverse()' где проблема начинается? –

+0

@DerekHunziker: 'Array.Reverse' - проблема. –

8

Если вы сделали расширение

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());