.NET Frameworkstringhe


Osservazioni

Nelle stringhe .NET System.String sono sequenze di caratteri System.Char , ogni carattere è un'unità di codice codificata UTF-16. Questa distinzione è importante perché la definizione del linguaggio parlata di carattere e la definizione di carattere .NET (e molte altre lingue) sono diverse.

Un carattere , che dovrebbe essere correttamente chiamato grafema , viene visualizzato come un glifo ed è definito da uno o più punti di codice Unicode. Ogni punto di codice è quindi codificato in una sequenza di unità di codice . Ora dovrebbe essere chiaro il motivo per cui un singolo System.Char non rappresenta sempre un grapheme, vediamo nel mondo reale come sono diversi:

  • Un grafema, a causa della combinazione di caratteri , può risultare in due o più punti di codice: à è composto da due punti di codice: U + 0061 LATIN LETTER A e U + 0300 LIVIN COMBINING GRAVE ACCENT . Questo è l'errore più comune perché "à".Length == 2 mentre ci si può aspettare 1 .
  • Ci sono caratteri duplicati, ad esempio à può essere un singolo punto di codice U + 00E0 LATIN SMALL LETTER A WITH GRAVE o due code-point come spiegato sopra. Ovviamente devono confrontare lo stesso: "\u00e0" == "\u0061\u0300" (anche se "\u00e0".Length != "\u0061\u0300".Length ). Ciò è possibile a causa della normalizzazione delle stringhe eseguita dal metodo String.Normalize() .
  • Una sequenza Unicode può contenere una sequenza composta o scomposta, per esempio il carattere U + D55C HAN CHARACTER può essere un singolo punto di codice (codificato come una singola unità di codice in UTF-16) o una sequenza decomposta delle sue sillabe , e . Devono essere paragonati allo stesso modo.
  • Un punto di codice può essere codificato su più di una unità di codice: carattere 𠂊 U + 2008A HAN CHARACTER è codificato come due System.Char ( "\ud840\udc8a" ) anche se è solo un punto di codice: UTF-16 la codifica non è una dimensione fissa! Questa è una fonte di innumerevoli bachi (anche gravi bug di sicurezza), se per esempio la tua applicazione applica una lunghezza massima e ciecamente tronca una stringa in quel momento, puoi creare una stringa non valida.
  • Alcune lingue hanno digraph e trigrammi, per esempio in ch ceco è una lettera standalone (dopo le ore e prima che io poi quando si ordina una lista di stringhe si dovrà fyzika prima Chemie.

Ci sono molti più problemi sulla gestione del testo, vedi per esempio Come posso eseguire un confronto con caratteri Unicode per confronto di caratteri? per un'introduzione più ampia e più collegamenti a argomenti correlati.

In generale, quando si tratta di testo internazionale , è possibile utilizzare questa semplice funzione per enumerare gli elementi di testo in una stringa (evitando di interrompere i surrogati e la codifica Unicode):

public static class StringExtensions
{
    public static IEnumerable<string> EnumerateCharacters(this string s)
    {
        if (s == null)
            return Enumerable.Empty<string>();

        var enumerator = StringInfo.GetTextElementEnumerator(s.Normalize());
        while (enumerator.MoveNext())
            yield return (string)enumerator.Value;
    }
}

stringhe Esempi correlati