Convertir deux caractères ascii à leur « correspondant » un caractère de représentation ascii étendu

StackOverflow https://stackoverflow.com/questions/2408657

Question

Le problème: J'ai deux chaînes de largeur fixe à partir d'un système externe. Le premier contient les caractères de base (comme a-z), le deuxième (mai) contenir des signes diacritiques être annexée à la première chaîne de caractères afin de créer les caractères réels.

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

//no clue what to do

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

Je pourrais écrire une recherche massive et remplacer tous les caractères + différents diacritiques mais espérait quelque chose d'un peu plus élégant.

Quelqu'un a une idée de comment corriger celui-ci? Essayé avec le calcul des valeurs décimales, en utilisant string.Normalize (c #), mais aucun résultat. Aussi Google ne tourne pas vraiment quelque chose.

Était-ce utile?

La solution

Je ne peux pas trouver une solution facile, sauf en utilisant des tables de consultation:

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

[EDIT: Code simplifié après suggestions dans les réponses de @JonB et @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;
    }
}

Autres conseils

Autre les diacritiques à des valeurs Unicode appropriées de la combinaison des signes diacritiques Unicode Gamme:

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

slap ensuite le omble chevalier et son diacritique ensemble par exemple pour e-aiguë, U + 0065 = "e" et U + 0301 = aigu.

  String s = "\u0065\u0301";

Alors:

  string normalisedString = s.Normalize();

combinera les deux dans une nouvelle chaîne.

Le problème est que les diacrits spécifiés doivent être explicitement analysé, en sorte que les doubles points n'existe pas seul et donc les guillemets doubles sont utilisés pour ce cas. Donc, pour accomplir votre problème, vous n'avez pas d'autre chance alors de mettre en œuvre chaque cas nécessaire.

Voici un point de départ pour obtenir un indice ...

    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;
        }
    }
}

Le IEnumerable.Zip est déjà mis en œuvre .Net 4 , mais pour l'obtenir à 3.5, vous aurez besoin de ce code ( tiré de 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);
    }
}

Je ne sais pas C #, ou ses bibliothèques standard, mais une autre approche pourrait être d'utiliser quelque chose comme un fichier HTML existant / SGML / parser entité de caractère XML / renderer, ou si vous allez vraiment vous présenter à un navigateur , rien

code pseudo:

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

Ainsi, A + o -> &Aring;, u + " -.> &uuml; etc.

Si vous pouvez analyser des entités html, vous devriez alors être à la maison libre, et même portable entre les jeux de caractères!

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top