Operazioni comuni sulle stringhe

Operazioni comuni sulle stringhe

# Formattazione di una stringa

Usa il String.Format() metodo per sostituire uno o più elementi nella stringa con la rappresentazione di stringa di un oggetto specificato:

String.Format("Hello {0} Foo {1}", "World", "Bar") //Hello World Foo Bar

# Riempimento di una stringa a una lunghezza fissa

string s = "Foo";
string paddedLeft = s.PadLeft(5);        // paddedLeft = "  Foo" (pads with spaces by default)
string paddedRight = s.PadRight(6, '+'); // paddedRight = "Foo+++"
string noPadded = s.PadLeft(2);          // noPadded = "Foo" (original string is never shortened)

# Invertire correttamente una stringa

La maggior parte delle volte, quando le persone devono invertire una stringa, lo fanno più o meno in questo modo:

char[] a = s.ToCharArray();
System.Array.Reverse(a);
string r = new string(a);

Tuttavia, ciò che queste persone non si rendono conto è che in realtà è sbagliato.
E non intendo a causa del controllo NULL mancante.

In realtà è sbagliato perché un Glyph/GraphemeCluster può essere costituito da diversi codepoint (ovvero caratteri).

Per capire perché è così, dobbiamo prima essere consapevoli del fatto che cosa significa effettivamente il termine "personaggio".

Riferimento:

Il carattere è un termine sovraccarico che può significare molte cose.

Un punto di codice è l'unità atomica dell'informazione. Il testo è una sequenza di punti di codice. Ogni punto di codice è un numero a cui viene attribuito un significato dallo standard Unicode.

Un grafema è una sequenza di uno o più punti di codice che vengono visualizzati come una singola unità grafica che un lettore riconosce come un singolo elemento del sistema di scrittura. Ad esempio, sia a che ä sono grafemi, ma possono essere costituiti da più punti di codice (ad es. ä può essere due punti di codice, uno per il carattere di base a seguito da uno per la diaresi; ma c'è anche un punto di codice alternativo, legacy, unico che rappresenta questo grafema ). Alcuni punti di codice non fanno mai parte di anygrapheme (ad es. il non joiner a larghezza zero o gli override direzionali).

Un glifo è un'immagine, solitamente memorizzata in un font (che è una raccolta di glifi), utilizzata per rappresentare grafemi o parti di essi. I caratteri possono comporre più glifi in un'unica rappresentazione, ad esempio, se il precedente ä è un singolo punto di codice, un carattere può scegliere di renderli come due glifi separati e sovrapposti nello spazio. Per OTF, le tabelle GSUB e GPOS del font contengono informazioni di sostituzione e posizionamento per far funzionare tutto questo. Un font può contenere anche più glifi alternativi per lo stesso grafema.

Quindi, in C#, un carattere è in realtà un CodePoint.

Ciò significa che se inverti una stringa valida come Les Misérables , che può assomigliare a questo

string s = "Les Mise\u0301rables";

come sequenza di caratteri, otterrai:

selbaŕesiM seL

Come puoi vedere, l'accento è sul carattere R, invece del carattere e.
Sebbene string.reverse.reverse restituirà la stringa originale se inverti entrambe le volte l'array di caratteri, questo tipo di inversione NON è sicuramente il contrario della stringa originale.

Dovrai invertire solo ogni GraphemeCluster.
Quindi, se fatto correttamente, inverti una stringa come questa:


   private static System.Collections.Generic.List<string> GraphemeClusters(string s)
    {
        System.Collections.Generic.List<string> ls = new System.Collections.Generic.List<string>();

        System.Globalization.TextElementEnumerator enumerator = System.Globalization.StringInfo.GetTextElementEnumerator(s);
        while (enumerator.MoveNext())
        {
            ls.Add((string)enumerator.Current);
        }

        return ls;
    }


    // this 
    private static string ReverseGraphemeClusters(string s)
    {
        if(string.IsNullOrEmpty(s) || s.Length == 1)
             return s;
        
        System.Collections.Generic.List<string> ls = GraphemeClusters(s);
        ls.Reverse();

        return string.Join("", ls.ToArray());
    }

    public static void TestMe()
    {
        string s = "Les Mise\u0301rables";
        // s = "noël";
        string r = ReverseGraphemeClusters(s);

        // This would be wrong:
        // char[] a = s.ToCharArray();
        // System.Array.Reverse(a);
        // string r = new string(a);

        System.Console.WriteLine(r);
    }

E - oh gioia - ti renderai conto che se lo fai correttamente in questo modo, funzionerà anche per le lingue asiatiche/sud-asiatiche/est-asiatiche (e francese/svedese/norvegese, ecc.)...

# Ottenere x caratteri dal lato destro di una stringa

Visual Basic dispone di funzioni Left, Right e Mid che restituiscono caratteri da Left, Right e Middle di una stringa. Questi metodi non esistono in C#, ma possono essere implementati con Substring() . Possono essere implementati come metodi di estensione come i seguenti:


  public static class StringExtensions
   {
      /// <summary>
      /// VB Left function
      /// </summary>
      /// <param name="stringparam"></param>
      /// <param name="numchars"></param>
      /// <returns>Left-most numchars characters</returns>
      public static string Left( this string stringparam, int numchars )
      {
         // Handle possible Null or numeric stringparam being passed
         stringparam += string.Empty;
    
         // Handle possible negative numchars being passed
         numchars = Math.Abs( numchars );
    
         // Validate numchars parameter        
         if (numchars > stringparam.Length)
            numchars = stringparam.Length;
    
         return stringparam.Substring( 0, numchars );
      }
    
      /// <summary>
      /// VB Right function
      /// </summary>
      /// <param name="stringparam"></param>
      /// <param name="numchars"></param>
      /// <returns>Right-most numchars characters</returns>
      public static string Right( this string stringparam, int numchars )
      {
         // Handle possible Null or numeric stringparam being passed
         stringparam += string.Empty;
    
         // Handle possible negative numchars being passed
         numchars = Math.Abs( numchars );
    
         // Validate numchars parameter        
         if (numchars > stringparam.Length)
            numchars = stringparam.Length;
    
         return stringparam.Substring( stringparam.Length - numchars );
      }
    
      /// <summary>
      /// VB Mid function - to end of string
      /// </summary>
      /// <param name="stringparam"></param>
      /// <param name="startIndex">VB-Style startindex, 1st char startindex = 1</param>
      /// <returns>Balance of string beginning at startindex character</returns>
      public static string Mid( this string stringparam, int startindex )
      {
         // Handle possible Null or numeric stringparam being passed
         stringparam += string.Empty;
    
         // Handle possible negative startindex being passed
         startindex = Math.Abs( startindex );
    
         // Validate numchars parameter        
         if (startindex > stringparam.Length)
            startindex = stringparam.Length;
         
         // C# strings are zero-based, convert passed startindex
         return stringparam.Substring( startindex - 1 );
      }
    
      /// <summary>
      /// VB Mid function - for number of characters
      /// </summary>
      /// <param name="stringparam"></param>
      /// <param name="startIndex">VB-Style startindex, 1st char startindex = 1</param>
      /// <param name="numchars">number of characters to return</param>
      /// <returns>Balance of string beginning at startindex character</returns>
      public static string Mid( this string stringparam, int startindex, int numchars)
      {
         // Handle possible Null or numeric stringparam being passed
         stringparam += string.Empty;
    
         // Handle possible negative startindex being passed
         startindex = Math.Abs( startindex );
    
         // Handle possible negative numchars being passed
         numchars = Math.Abs( numchars );
    
         // Validate numchars parameter        
         if (startindex > stringparam.Length)
            startindex = stringparam.Length;
    
         // C# strings are zero-based, convert passed startindex
         return stringparam.Substring( startindex - 1, numchars );

       }
    }

Questo metodo di estensione può essere utilizzato come segue:

string myLongString = "Hello World!";
string myShortString = myLongString.Right(6);  // "World!"
string myLeftString = myLongString.Left(5);    // "Hello"
string myMidString1 = myLongString.Left(4);    // "lo World"
string myMidString2 = myLongString.Left(2,3);    // "ell"

# Controllo della stringa vuota utilizzando String.IsNullOrEmpty() e String.IsNullOrWhiteSpace()

string nullString = null;
string emptyString = "";
string whitespaceString = "    ";
string tabString = "\t";
string newlineString = "\n";
string nonEmptyString = "abc123";

bool result;

result = String.IsNullOrEmpty(nullString);            // true
result = String.IsNullOrEmpty(emptyString);           // true
result = String.IsNullOrEmpty(whitespaceString);      // false
result = String.IsNullOrEmpty(tabString);             // false
result = String.IsNullOrEmpty(newlineString);         // false
result = String.IsNullOrEmpty(nonEmptyString);        // false

result = String.IsNullOrWhiteSpace(nullString);       // true
result = String.IsNullOrWhiteSpace(emptyString);      // true
result = String.IsNullOrWhiteSpace(tabString);        // true
result = String.IsNullOrWhiteSpace(newlineString);    // true
result = String.IsNullOrWhiteSpace(whitespaceString); // true
result = String.IsNullOrWhiteSpace(nonEmptyString);   // false

# Taglio dei caratteri indesiderati all'inizio e/o alla fine delle stringhe.

# String.Trim()

string x = "   Hello World!    ";
string y = x.Trim(); // "Hello World!"

string q = "{(Hi!*";
string r = q.Trim( '(', '*', '{' ); // "Hi!"

# String.TrimStart() e String.TrimEnd()

string q = "{(Hi*";
string r = q.TrimStart( '{' ); // "(Hi*"
string s = q.TrimEnd( '*' );   // "{(Hi" 

# Costruisci una stringa da Array

Il String.Join il metodo ci aiuterà a costruire una stringa da matrice/elenco di caratteri o stringa. Questo metodo accetta due parametri. Il primo è il delimitatore o il separatore che ti aiuterà a separare ogni elemento nell'array. E il secondo parametro è l'array stesso.

Stringa da char array :

string delimiter=",";
char[] charArray = new[] { 'a', 'b', 'c' };
string inputString = String.Join(delimiter, charArray);

Risultato :a,b,c se cambiamo il delimiter come "" quindi l'output diventerà abc .

Stringa da List of char :

string delimiter = "|";
List<char> charList = new List<char>() { 'a', 'b', 'c' };
string inputString = String.Join(delimiter, charList);

Risultato :a|b|c

Stringa da List of Strings :

string delimiter = " ";
List<string> stringList = new List<string>() { "Ram", "is", "a","boy" };
string inputString = String.Join(delimiter, stringList);

Risultato :Ram is a boy

Stringa da array of strings :

string delimiter = "_";
string[] stringArray = new [] { "Ram", "is", "a","boy" };
string inputString = String.Join(delimiter, stringArray);

Risultato :Ram_is_a_boy

# Formattazione utilizzando ToString

Di solito utilizziamo String.Format metodo per la formattazione, il .ToString viene solitamente utilizzato per convertire altri tipi in string. Possiamo specificare il formato insieme al metodo ToString durante la conversione, quindi possiamo evitare una formattazione aggiuntiva. Lasciami spiegare come funziona con diversi tipi;

Intero in stringa formattata:

int intValue = 10;
string zeroPaddedInteger = intValue.ToString("000"); // Output will be "010"
string customFormat = intValue.ToString("Input value is 0"); // output will be   "Input value is 10" 

stringa doppia in formattata:

double doubleValue = 10.456;
string roundedDouble = doubleValue.ToString("0.00"); // output 10.46
string integerPart = doubleValue.ToString("00");    // output 10
string customFormat = doubleValue.ToString("Input value is 0.0");  // Input value is 10.5

Formattare DateTime utilizzando ToString

DateTime currentDate = DateTime.Now; //  {7/21/2016 7:23:15 PM}
string dateTimeString = currentDate.ToString("dd-MM-yyyy HH:mm:ss"); // "21-07-2016 19:23:15"
string dateOnlyString = currentDate.ToString("dd-MM-yyyy"); // "21-07-2016"
string dateWithMonthInWords = currentDate.ToString("dd-MMMM-yyyy HH:mm:ss"); // "21-July-2016 19:23:15"

# Converti numero decimale in formato binario, ottale ed esadecimale

  • Per convertire il numero decimale in formato binario, usa **base 2**
    Int32 Number = 15;
    Console.WriteLine(Convert.ToString(Number, 2));  //OUTPUT : 1111
    
    
  • Per convertire il numero decimale in formato ottale usa **base 8**
    int Number = 15;
    Console.WriteLine(Convert.ToString(Number, 8));  //OUTPUT : 17
    
    
  • Per convertire il numero decimale in formato esadecimale usa **base 16**
    var Number = 15;
    Console.WriteLine(Convert.ToString(Number, 16));  //OUTPUT : f
    
    
  • # Suddivisione di una stringa per carattere specifico

    string helloWorld = "hello world, how is it going?";
    string[] parts1 = helloWorld.Split(',');
    
    //parts1: ["hello world", " how is it going?"]
    
    string[] parts2 = helloWorld.Split(' ');
    
    //parts2: ["hello", "world,", "how", "is", "it", "going?"]
    
    

    # Ottenere sottostringhe di una determinata stringa

    string helloWorld = "Hello World!";
    string world = helloWorld.Substring(6); //world = "World!"
    string hello = helloWorld.Substring(0,5); // hello = "Hello"
    
    

    Substring restituisce la stringa a partire da un determinato indice o tra due indici (entrambi inclusi).

    # Determina se una stringa inizia con una determinata sequenza

    string HelloWorld = "Hello World";
    HelloWorld.StartsWith("Hello"); // true
    HelloWorld.StartsWith("Foo"); // false
    
    

    Trovare una stringa all'interno di una stringa

    Usando il System.String.Contains puoi scoprire se una stringa particolare esiste all'interno di una stringa. Il metodo restituisce un valore booleano, true se la stringa esiste altrimenti false.

    string s = "Hello World";
    bool stringExists = s.Contains("ello");  //stringExists =true as the string contains the substring 
    
    

    # Unire un array di stringhe in uno nuovo

    var parts = new[] { "Foo", "Bar", "Fizz", "Buzz"};
    var joined = string.Join(", ", parts);
    
    //joined = "Foo, Bar, Fizz, Buzz"
    
    

    # Ottenere un carattere in un indice specifico ed enumerare la stringa

    Puoi usare il Substring metodo per ottenere un numero qualsiasi di caratteri da una stringa in una determinata posizione. Tuttavia, se desideri un solo carattere, puoi utilizzare l'indicizzatore di stringhe per ottenere un singolo carattere in un dato indice come faresti con un array:

    string s = "hello";
    char c = s[1]; //Returns 'e'
    
    

    Nota che il tipo restituito è char , a differenza del Substring metodo che restituisce un string digitare.

    Puoi anche usare l'indicizzatore per scorrere i caratteri della stringa:

    string s = "hello";
    foreach (char c in s)
        Console.WriteLine(c);
    /********* This will print each character on a new line:
    h
    e
    l
    l
    o
    **********/
    
    

    # Dividere una stringa per un'altra stringa

    string str = "this--is--a--complete--sentence";
    string[] tokens = str.Split(new[] { "--" }, StringSplitOptions.None);
    
    

    Risultato:

    [ "questo", "è", "a", "completo", "frase" ]

    # Sostituzione di una stringa all'interno di una stringa

    Usando il System.String.Replace metodo, puoi sostituire parte di una stringa con un'altra stringa.

    string s = "Hello World";
     s = s.Replace("World", "Universe"); // s = "Hello Universe"
    
    

    Tutte le occorrenze della stringa di ricerca vengono sostituite.

    Questo metodo può essere utilizzato anche per rimuovere parte di una stringa, utilizzando il String.Empty campo:

    string s = "Hello World";
    s = s.Replace("ell", String.Empty); // s = "Ho World"
    
    

    # Modifica delle maiuscole e minuscole dei caratteri all'interno di una stringa

    Il System.String class supporta una serie di metodi per convertire tra caratteri maiuscoli e minuscoli in una stringa.

    • System.String.ToLowerInvariant viene utilizzato per restituire un oggetto String convertito in minuscolo.

    • System.String.ToUpperInvariant viene utilizzato per restituire un oggetto String convertito in maiuscolo.

    Nota: Il motivo per utilizzare l'invariante versioni di questi metodi serve a prevenire la produzione di lettere specifiche della cultura impreviste. Questo è spiegato qui in dettaglio.

    Esempio:

    string s = "My String";
    s = s.ToLowerInvariant(); // "my string"
    s = s.ToUpperInvariant(); // "MY STRING"
    
    

    Tieni presente che puoi scegli di specificare una specifica Cultura durante la conversione in minuscolo e maiuscolo utilizzando i metodi String.ToLower(CultureInfo) e String.ToUpper(CultureInfo).

    # Concatena un array di stringhe in una singola stringa

    Il System.String.Join il metodo consente di concatenare tutti gli elementi in un array di stringhe, utilizzando un separatore specificato tra ogni elemento:

    string[] words = {"One", "Two", "Three", "Four"};
    string singleString = String.Join(",", words); // singleString = "One,Two,Three,Four"
    
    

    # Concatenazione di stringhe

    La concatenazione di stringhe può essere eseguita utilizzando il System.String.Concat metodo o (molto più semplice) utilizzando il + operatore:

    string first = "Hello ";
    string second = "World";
    
    string concat = first + second; // concat = "Hello World"
    concat = String.Concat(first, second); // concat = "Hello World"
    
    

    In C# 6 questo può essere fatto come segue:

    string concat = $"{first},{second}";