2010-03-09 13 views
6

Das Problem: Ich habe zwei feste Breite Zeichenfolgen aus einem externen System. Die erste enthält die Basiszeichen (wie a-z), die zweite (MAY) enthält diakritische Zeichen, die an die erste Zeichenfolge angehängt werden, um die eigentlichen Zeichen zu erstellen.Konvertieren Sie zwei ASCII-Zeichen in ihre "entsprechende" ein Zeichen erweiterte ASCII-Darstellung

string asciibase = "Dutch has funny chars: a,e,u"; 
string diacrits = "      ' \" \""; 

//no clue what to do 

string result = "Dutch has funny chars: á,ë,ü"; 

Ich könnte eine massive Suche und ersetzen für alle Charaktere + verschiedene diakritische Zeichen schreiben, wurde aber nach etwas elegantere der Hoffnung.

Jemand hat eine Ahnung, wie man das repariert? Versucht es mit der Berechnung der Dezimalwerte, mit string.Normalize (C#), aber keine Ergebnisse. Google hat auch nicht wirklich etwas gefunden.

+0

Sie suchen das Gegenteil von string.Normalize, ich fürchte, es gibt keine eingebaute Methode, um zu bekommen, was Sie wollen ... –

+0

Ich denke, er ist nach Normalisierung, es ist nur, dass seine Diakritika sind nicht die Kombination von Zeichen so es funktioniert nicht. –

Antwort

1

ich nicht eine einfache Lösung, außer der Verwendung von Lookup-Tabellen finden:

public void TestMethod1() 
{ 
    string asciibase = "Dutch has funny chars: a,e,u"; 
    string diacrits = "      ' \" \""; 
    var merged = DiacritMerger.Merge(asciibase, diacrits); 
} 

[EDIT: Vereinfachtes Code nach Anregungen in den Antworten von @JonB und @Oliver]

public class DiacritMerger 
{ 
    static readonly Dictionary<char, char> _lookup = new Dictionary<char, char> 
         { 
          {'\'', '\u0301'}, 
          {'"', '\u0308'} 
         }; 

    public static string Merge(string asciiBase, string diacrits) 
    { 
     var combined = asciiBase.Zip(diacrits, (ascii, diacrit) => DiacritVersion(diacrit, ascii)); 
     return new string(combined.ToArray()); 
    } 

    private static char DiacritVersion(char diacrit, char character) 
    { 
     char combine; 
     return _lookup.TryGetValue(diacrit, out combine) ? new string(new [] {character, combine}).Normalize()[0] : character; 
    } 
} 
1

Das Problem ist, dass die angegebenen diakrits explizit geparst werden müssen, da die doppelten Punkte nicht allein existieren und daher die doppelten Anführungszeichen für diesen Fall verwendet werden. Um Ihr Problem zu lösen, haben Sie dann keine andere Chance, jeden benötigten Fall zu implementieren.

Hier ist ein Ausgangspunkt einen Anhaltspunkt zu bekommen ...

public SomeFunction() 
    { 
     string asciiChars = "Dutch has funny chars: a,e,u"; 
     string diacrits = "      ' \" \""; 

     var combinedChars = asciiChars.Zip(diacrits, (ascii, diacrit) => 
     { 
      return CombineChars(ascii, diacrit); 
     }); 

     var Result = new String(combinedChars.ToArray()); 
    } 

    private char CombineChars(char ascii, char diacrit) 
    { 
     switch (diacrit) 
     { 
      case '"': 
       return AddDoublePoints(ascii); 
      case '\'': 
       return AddAccent(ascii); 
      default: 
       return ascii; 
     } 
    } 

    private char AddDoublePoints(char ascii) 
    { 
     switch (ascii) 
     { 
      case 'a': 
       return 'ä'; 
      case 'o': 
       return 'ö'; 
      case 'u': 
       return 'ü'; 
      default: 
       return ascii; 
     } 
    } 

    private char AddAccent(char ascii) 
    { 
     switch (ascii) 
     { 
      case 'a': 
       return 'á'; 
      case 'o': 
       return 'ó'; 
      default: 
       return ascii; 
     } 
    } 
} 

Die IEnumerable.Zip ist bereits implemented in .Net 4, aber es in 3,5 bekommen Sie diesen Code benötigen (taken from Eric Lippert):

public static class IEnumerableExtension 
{ 
    public static IEnumerable<TResult> Zip<TFirst, TSecond, TResult> 
     (this IEnumerable<TFirst> first, 
     IEnumerable<TSecond> second, 
     Func<TFirst, TSecond, TResult> resultSelector) 
    { 
     if (first == null) throw new ArgumentNullException("first"); 
     if (second == null) throw new ArgumentNullException("second"); 
     if (resultSelector == null) throw new ArgumentNullException("resultSelector"); 
     return ZipIterator(first, second, resultSelector); 
    } 

    private static IEnumerable<TResult> ZipIterator<TFirst, TSecond, TResult> 
     (IEnumerable<TFirst> first, 
     IEnumerable<TSecond> second, 
     Func<TFirst, TSecond, TResult> resultSelector) 
    { 
     using (IEnumerator<TFirst> e1 = first.GetEnumerator()) 
     using (IEnumerator<TSecond> e2 = second.GetEnumerator()) 
      while (e1.MoveNext() && e2.MoveNext()) 
       yield return resultSelector(e1.Current, e2.Current); 
    } 
} 
+0

Die Lösung, die Sie geben, war der einzige einfache Weg, den ich gefunden habe - aber auch die meisten Gehirn-Tötung ... Ich halte es für den letzten Ausweg;) –

+1

Nach dem Lesen der anderen Antworten sollten Sie möglicherweise eine gute Lösung durch die Kombination finden alle von ihnen (wie Mikael in seiner Post) in irgendeiner Weise. – Oliver

4

Konvertieren Sie die diakritischen Zeichen auf geeignete Unicode-Werte aus dem Unicode Kombinieren diakritischen Zeichen reichen:

http://www.unicode.org/charts/PDF/U0300.pdf

Dann schlagen Sie den char und seine diakritische zusammen z für E-Akut, U + 0065 = "e" und U + 0301 = akut.

String s = "\u0065\u0301"; 

Dann:

string normalisedString = s.Normalize(); 

werden die beiden in eine neue Zeichenfolge kombinieren.

0

Ich kenne C# oder seine Standardbibliotheken nicht, aber ein alternativer Ansatz könnte darin bestehen, etwas wie einen vorhandenen HTML/SGML/XML-Zeichenentitäts-Parser/-Renderer zu verwenden, oder wenn Sie ihn tatsächlich einem Browser, nichts!

Pseudo-Code:

for(i=0; i < strlen(either_string); i++) { 
    if isspace(diacrits[i]) { 
    output(asciibase[i]); 
    }else{ 
    output("&"); 
    output(asciibase[i]); 
    switch (diacrits[i]) { 
     case '"' : output "uml"; break; 
     case '^' : output "circ"; break; 
     case '~' : output "tilde"; break; 
     case 'o' : output "ring"; break; 
     ... and so on for each "code" in the diacrits modifier 
     ... (for acute, grave, cedil, lig, ...) 
    } 
    output(";"); 
    } 
} 

So A + o ->&Aring;, u + " ->&uuml; und so weiter.

Wenn Sie dann HTML-Entitäten analysieren können, sollten Sie dann frei und sogar tragbar zwischen Zeichensätzen sein!

Verwandte Themen