Im folgenden Artikel möchte ich die String-Klasse aus dem .NET 4.0 Framework und deren Möglichkeiten zeigen, sowie das effektive Arbeiten mit dieser Klasse. Hierbei versuche ich kurz und knapp vorzugehen, um einen schnellen Überblick zu schaffen.

Definition

Ein String ist ein Referenztyp und repräsentiert eine nicht veränderbare Kette von Unicode-Zeichen. Ein Unicode-Zeichen nimmt dabei ein Größe von 2 Byte ein.

Ein String-Literal wird immer in doppelten Anführungszeichen angegeben.

Hello World

Ein einfaches Zuweisen einer String-Variable

string s1 = "Hello World";

Einen leeren String zuweisen

string s6 = String.Empty;
string s7 = "";

Einen String auf null oder leer prüfen

String.IsNullOrEmpty(string.Empty)

Einen String auf Null, leer oder Leerzeichen prüfen

Als NullOrWhiteSpace wird auch bei einigen Escapesequenzen, wie Tab (vertikal, horizontal), Wagenrücklauf, Seitenvorschub und neue Zeile “true” zurück gegeben.

string sp = " ";
bool b1 = String.IsNullOrWhiteSpace(sp);
//Ausgabe true

string sp1 = "\n\r\t\f\v";
bool b2 = String.IsNullOrWhiteSpace(sp1);
//Ausgabe true


Länge einer Zeichenkette ermitteln

int length = "Hello World".Length;
//Ausgabe 11


Leerzeichen entfernen

TrimStart() entfernt alle führenden Leerzeichen, vom Anfang eines Strings

TrimEnd() entfernt alle führenden Leerzeichen, vom Ende eines Strings

Trim() entfernt alle führenden Leerzeichen sowohl vom Anfang als auch vom Ende

Wird den Methoden ein char als Parameter mitgegeben, wird dieser, sofern dieser führend ist, entfernt.

string t1 = " Hello World ";

string t2 = t1.Trim();
//Ausgabe: "Hello World"

string s3 = t1.TrimEnd();
//Ausgabe: " Hello World"

string s4 = t1.TrimStart();
//Ausgabe: "Hello World "

string s5 = t1.Trim().Trim('H');
//Ausgabe: "ello World"
            
string s6 = t1.Trim().Trim('H').TrimEnd('d');
//Ausgabe: "ello Worl"


Strings splitten

string sp1 = "Hello World";
string[] splittedString = sp1.Split();            

String anhand bestimmter Zeichen splitten

string[] stringArr = "Hello <br />World".Split(new[] { "<br />" }, StringSplitOptions.None);

Der Enumeration Parameter StringSplitOptions bietet mit StringSplitOptions.RemoveEmptyEntries die Möglichkeit, leere Zeichen beim splitten zu entfernen, diese werden dann nicht im Array mit aufgenommen. Mit StringSplitOptions.None werden auch die Leerzeichen als String im Array mit aufgenommen.

string[] stringArr = "Hello      World".Split(new[] { " " }, StringSplitOptions.None);
//Ausgabe length: 7
string[] stringArr2 = "Hello      World".Split(new[] { " " }, StringSplitOptions.RemoveEmptyEntries);
//Ausgabe length: 2


Strings verketten

Um Strings miteinander zu verketten, verwendet man den + Operator.

string o1 = "Hello " + "World";
string o2 = "Hello ";
o2 += "World";

Dabei muss der rechte Operand kein String sein. Hier findet eine implizite Konvertierung statt:

string o3 = "Mario Priebe, " + 38;

Mit Concat() werden Strings miteinander verkettet:

string c1 = "Hello ";
string c2 = string.Concat(c1, " World");
string c3 = string.Concat(c1, " new", " World");

Zu “Verketten von Strings”, siehe auch StringBuilder!


Strings kopieren

string a1 = "Hello World";
string a2 = String.Copy(a1);
string a3 = a1.Clone().ToString(); //kopieren des Zeigers (neuer Verweis)


ToUpper, ToLower

Um die Groß- und Kleinschreibung für eine Zeichenkette zu handlen, bedient man sich der Methoden ToUpper() und ToLower().

string sp1 = "Hello World";
string sp2 = sp1.ToUpper();
//Ausgabe: HELLO WORLD

string sp3 = sp1.ToLower();
//Ausgabe: hello world

Möchte man nun strings miteinander vergleichen, ist es plausibel diese erst einmal auf eine der Schreibarten zu konvertieren.

string sp1 = "Hello World";
bool b1 = sp1.ToUpper() == "HELLO WORLD";
//Ausgabe true

Hat man jedoch Sprachen, wie z.B. die Türkische, kommt es vor dass das Ergebnis verfälscht wird. Wie bei dem Zeichen İ (großes I mit Punkt) z.B. Wenn ich nun “i”.ToUpper() mit İ vergleiche, bekomme ich false. Hier sollte man dann auf die Methode ToUpperInvariant() zurückgreifen.

string sp1 = "i";
bool b1 = sp1.ToUpper() == "İ";
//Ausgabe false

bool b2 = sp1.ToUpper(CultureInfo.CreateSpecificCulture("tr-TR")) == "İ".ToUpperInvariant();
//Ausgabe true


Innerhalb eines Strings suchen

Innerhalb eines Strings kann man über den Indexxer auf eine bestimmte Position zugreifen. Dabei wird von 0 an gezählt.

Bei einem String, der “Hello World” darstellt, ist der sechste Index somit das Zeichen W.

string s1 = "Hello World";
char c1 = s1[6];

IndexOf, IndexOfAny

Die Methoden IndexOf und IndexOfAny suchen innerhalb eines Strings nach einen bestimmten Zeichen und geben die Position als Integer zurück.

IndexOf

string st1 = "Hello World";
int indexOf = st1.IndexOf("o");
//Ausgabe: 4

IndexOfAny

IndexOfAny findet das erste Vorkommen, der in den Parametern enthaltenen Kriterien, innerhalb eines Strings, dabei können mehrere Kriterien, in Form eines Char-Arrays als Parameter übergeben werden.

string st1 = "Hello World";
int indexOfAny = st1.IndexOfAny(new char[] { 'o', 'l' });
//Ausgabe 2

LastIndexOfAny findet das letzte Vorkommen der in den Parametern übergebenen Zeichen.

string st1 = "Hello World";
int lastIndexOfAny = st1.LastIndexOfAny(new char[] { 'o', 'l' });
//Ausgabe: 9

Contains, StartsWith, EndsWith

Die Methoden Contains, StartsWith und EndWith suchen nach einem Teilstring innerhalb des Strings.

Contains

string st1 = "Hello World";
bool b1 = st1.Contains(" Wo");
//true

bool b2 = st1.Contains(" wo");
//false

bool b3 = st1.ToLower().Contains(" wo");
//true

StartsWith, EndWith

string st1 = "Hello World";
bool startsWith = st1.StartsWith("He");
//true

bool endWith = st1.EndsWith("ld");
//true


Das Verändern eines Strings

Teilstrings aus einem String ermitteln

Substring() ermittelt eine Zeichenkette innerhalb eines Strings.

string o3 = "Hello World";
string s1 = o3.Insert(5, " new ");
string s2 = s1.Substring(5, 5);
//Ausgabe: " new "

Insert, Remove

Diese beiden Methoden ermöglichen zum einen das Einfügen (Insert) und zum anderen das Entfernen (Remove) eines SubStrings innerhalb eines Strings.

string o3 = "Hello World";
string s1 = o3.Insert(5, " new ");
//Ausgabe: Hello new World

string o3 = "Hello World";
string s1 = o3.Insert(5, " new ");
string s2 = s1.Remove(5, 5);
//Ausgabe Hello World

PadLeft, PadRight

Die Methoden PadLeft und PadRight ermöglichen das Ausrichten eines Strings. Die restlichen Zeichen werden dabei mit dem angegebenen Zeichens aufgefüllt.

string sp1 = "Hello World".PadRight(50, '-');
//Ausgabe: Hello World---------------------------------------

string sp2 = "Hello World".PadLeft(50, '-');
//Ausgabe: ---------------------------------------Hello World


Strings vergleichen

Equals(), vergleicht zwei Zeichenketten miteinander

string e1 = " Hello World ";
string e2 = " Hello World ";
bool b1 = string.Equals(e1, e2);
//Ausgabe: true

Compare(), vergleicht zwei Zeichenketten, und gibt einen Integer zurück, der die jeweilige Position in der Sortierung angibt. Der Integer beschreibt, ob der erste Wert lexikalisch vor (-1), nach (1), oder gleich (0) des zweiten übergebenen Wertes ist.

int c1 = string.Compare("a", "b");
//Ausgabe: -1

int c2 = string.Compare("b", "a");
//Ausgabe: 1

int c3 = string.Compare("a", "a");
//Ausgabe: 0

Weitere Überladungen bieten die Angabe der Position des jeweiligen Zeichens, welches verglichen werden soll.

Möchte man die absolute Differenz in der lexikalischen Beziehung ermitteln, verwendet man CompareOrdinal()

int o1 = string.CompareOrdinal("Hello", "World");
//Ausgabe: -15 (H ist 15 Zeichen kleiner als W)

CompareTo(), wie Compare, nur hier wird die aktuelle Instanz mit einem String, welcher als Parameter der Methode übergeben wird, verglichen.

int c4 = "abc".CompareTo("abc");
//Ausgabe: 0

An Equals, Compare und CompareTo kann man weitergehende Einstellungen bezüglich der Art und Weise eines Vergleichs wie z.B. länderspezifische Informationen, Groß- und Kleinschreibungen berücksichtigen. Dazu steht einem die Enumeration StringComparision zur Verfügung.

StringComparision

Gibt die Kultur, die Groß- und Kleinschreibung und die Sortierreihenfolge an.

  • CurrentCulture (case-sensitve)
  • CurrentCultireIgnoreCase
  • InvariantCulture (case-sensitve)
  • InvariantCultureIgnoreCase
  • Ordinal (case-sensitve)
  • OrdinalIgnoreCase

Escapesequenzen in einem String verwenden.

string s2 = "Hello\r\nWorld";

Weitere Escapesequenzen:

Excapesequenz Beschreibung
\’ Ausgabe eines Apostrophs
\\ Ausgabe eines Backslashes
\” Ausgabe von Anführungsstrichen
\0 Markieren vom Ende einer Zeichenkette
\b Rückschritt
\n Neue Zeile (Linefeed)
\r Wagenrücklauf (carriage return)
\t Tabulator (horizontal)
\v Tabulator (vertikal)
\a Alert
\f Seitenvorschub

Die Escapesequenzen \u oder \x ermöglichen es, ein char über seinen vierstelligen HexadecimalCode darzustellen. z.B.

char copy = '\u00A9';
char trademark = '\u00AE';
char cent = '\x00A2';
char micro = '\x00B5';

Wenn man von einem Zeichen den jeweiligen HexaCode ermitteln möchte, kann man dazu folgenden Methode verwenden:

public string CharToHex(char c)
{
    return "0x" + Convert.ToInt32(c).ToString("X");
} 

Verbatim String Literal

Alle im String enthaltene Zeichen werden interpretiert. Anführungszeichen müssen doppelt oder wie oben beschrieben mittels Escapesequenz als solche angegeben werden.

string  s3 = @"Hello\World.txt";

string s4 = @"Hier steht eine ""Menge"" Text aber das macht nicht's";


Strings konvertieren

Einen String in ein char array konvertieren

string myString = "Hello World";
char[] charArr = myString.ToCharArray();

Ein char array in einen String konvertieren

string s4 = new String(charArr);


Mehrfach wiederholende Zeichen als String darstellen

string s5 = new String('*', 5);


Formatieren von Zeichenketten (Platzhalter, Decimal-, Währungs und Datumsangaben).

Formatierungszeichen

Zeichen Beschreibung
0 Platzhalter für Ziffern (oder 0)
# Platzhalter für Ziffern (oder nichts)
. Platzhalter für Decimaltrennzeichen
, Platzhalter für Tausendertrennzeichen
% Platzhalter für Prozentzeichen
+ / – Vorzeichen
C / c Währungsformat mit Tausendertrennzeichen und zwei Decimalstellen. Währungszeichen hängt von den Einstellungen ab
D / d decimale Ausgabe
E / e wissenschaftliche Ausgabe
F / f Darstellung von Gleitkommazahlen mit festem Komma
G / g Allgemeine Gleitkommazahl
N / n Ausgabe von Ziffern mit Tausendertrennzeichen
P / p Ausgabe in Prozent
X / x Hexadecimale Ausgabe
hh:mm:ss / HH:mm:ss Zeigt Stunden, Minuten und Sekunden mit führender Null an, 12h (hh) und 24h (HH) Format
dd Tag mit führender 0
dddd ausgeschriebener Wochentag
MM Monat mit mit führender 0
MMMM ausgeschriebener Monat
yy / yyyy das Jahr zwei- bzw. vierstellig
d Datum in Kurzform
D Datum im Langformat
F Datum und Uhrzeit im Langformat
g Datum und Uhrzeit im Lang- und 24h Format
t Uhrzeit im Kurzformat
T Uhrzeit im Langformat

string val = String.Format("Heute ist der {0:dd}. Tag im Monat {0:MMMM}", DateTime.Now);
            //Ausgabe: Heute ist der 26. Tag im Monat Juni

string f1 = String.Format("Platz {0:#} von {1:#}", 5, 12);


Die StringBuilder-Klasse

Da das Verketten von Strings mit den + Operator, bzw. das Manipulieren des Strings an sich, sehr ineffizient sein kann, sollte man hier lieber auf die Klasse StringBuilder zurückgreifen. Da hier schneller auf den Speicher zugegriffen werden kann und beim Arbeiten mit einem String, dieser nicht unnötig hin & her kopiert werden muss.

Der StringBuilder repräsentiert einen veränderbaren String und bietet zudem auch mehrere Methoden, den String zu manipulieren. Die Länge der Zeichenkette ist variabel und der Speicherbedarf wird dynamisch angepasst. Die maximale Kapazität kann mittels Konstruktor angegeben und beeinflusst werden.

StringBuilder sb = new StringBuilder(1, 30);
//maximale Stringlänge 30

Append(), fügt eine Zeichenkette an

StringBuilder sb = new StringBuilder("Hello");
sb.Append(" World");
//Ausgabe: Hello World

AppendFormat(), fügt eine Zeichenkette mit Formatierung an

StringBuilder sb = new StringBuilder("Hello");
sb.AppendFormat(" {0} ", "new");
sb.Append("World");
//Ausgabe: Hello new World

Insert(), fügt an der angegebenen Position Zeichenketten ein

StringBuilder sb = new StringBuilder("Hello");
sb.Append("World");
sb.Insert(5, " new ");
//Ausgabe: Hello new World

Remove(), entfernt Zeichenketten aus der angegebene Position.

StringBuilder sb = new StringBuilder("Hello");
sb.Append("World");
sb.Insert(5, " new ");
sb.Remove(5, 4);
//Ausgabe: Hello World

Replace(), Ersetzt einzelne Zeichen oder Zeichenketten

StringBuilder sb = new StringBuilder("Hello");
sb.Append("World");
sb.Insert(5, " new ");
sb.Replace("new", "old");
//Ausgabe: Hello old World

Wenn man also viel bzw. mit großen Zeichenketten  arbeitet, wird die Verwendung des StringBuilders dringend empfohlen.

Ich hoffe dieser Artikel konnte einen kleinen Einblick in die Zeichenkettenverarbeitung innerhalb des .NET Frameworks schaffen. Wenn dem einen oder anderen Leser hier noch was fehlen sollte, immer rein damit in die Kommentarfunktion.

In diesem Sinne, viel Spaß beim entwickeln : )

C# 4.0 Grundlagen / String & Texthandling
Markiert in:    
  • Ach ist das schön dass auch mal jemand an die Anfänger denkt. *thumbs up*
    Eigentlich müsste ich mich schämen. Mir geistern schon lange Anfängerthemen für Blogartikel im Kopf herum, aber ich habe mich nie getraut sie zu schreiben.

  • Jep, da hast du recht. Irgendwann ist die Messlatte so hoch gesteckt, da bleibt nur der Rückzug : )

    • Gratuliere zu dem guten Artikel. Dies Messlatten sind allerdings auch generell hoch gesteckt, sodass einem die Themen meistens ausgehen, wenn man gesehen hat dass eine bekannte .NET eventuell bereits darüber geschrieben hat.

      Finde den Artikel, kurz, gut und knackig. Weiter so.

  • Pingback: C# 4.0 Grundlagen / String & Texthandling | Biggle's Blog()

  • Es ist doch immer wieder spannend, wenn man „neue“ Methoden kennenlernt, die bereits seit .NET 1.0 im Framework enthalten sind. String.IndexOfAny(Char[]) sowie String.CompareOrdinal(Char[]) sind solche Kandidaten …

    In der Hinsicht: Danke für die späte Einsicht :)!

  • Pingback: KW27: Unity3D Coroutine, Dr Web, HTML5 und mehr - Der Softwareentwickler Blog()