Geschrieben von: Christian Holm
Kategorie: C#
This printed page brought to you by AlphaSierraPapa
Diesmal beschäftigen wir uns mit dem Funktionsumfang der String Klasse in C#. Ausgehend von einfachen Beispielen werde ich Möglichkeiten wie das Splitten von Strings, Finden von Zeichen und Zeichenketten, das Trimmen von Strings und vieles mehr besprechen. Abschließend präsentiere ich Ihnen noch die effizientere Methode der Stringbehandlung mit der StringBuilder Klasse.
Voraussetzung um den Sourcecode dieses Artikels verwenden zu können ist eine Installation des Microsoft .NET Framework SDK's auf einem Webserver. Weiters setze ich voraus, daß der Leser die Programmiersprache C# zu einem gewissen Grad beherrscht - es finden sich etliche Artikel auf diesem Server, um das notwendige Wissen zu erlernen.
Die String Klasse enthält Methoden um Strings zu vergleichen, formatieren und manipulieren. Methoden wie Replace (Ersetzen), Remove (Entfernen) und Trim (Kürzen) erzeugen bei Verwendung einen neuen String, der auf dem orginalen basiert. Dies geschieht deshalb, weil eine Instanz von einem String nach dessen Erstellung nicht mehr verändert werden kann.
Die Position (Index) der Zeichen in einem String beginnt, wie bei Arrays, mit 0. Die Methoden für den Vergleich und die Suche von Strings sind case-sensitive. Wenn man Vergleiche von Texten durchführt, sollte man die Compare (vergleichen) und Equals (entspricht) Methoden verwenden, welche von der String Klasse zur Verfügung gestellt werden.
Diese Methoden überprüfen Strings auf Referenzgleicheit, falls sie nicht vom Programmierer überladen werden. Das Framework ermöglicht aber auch String Objekte mit relationalen Operatoren zu vergleichen. Ein dynamisch erstellter String, welcher durch den StringBuilder oder durch die String-Klassenmethoden Replace, Remove oder Trim erzeugt wurde, können nicht mit relationalen Operatoren verglichen werden. Hier müssen die Methoden Compare oder Equals verwendet werden.
Die String-Klasse hat nur 2 Eigenschaften, und diese lassen sich in einem Beispiel verpacken - in diesem Beispiel möchte ich Ihnen zeigen, wie man einen String als Folge von Zeichen ausgibt charsindexer.aspx:
<% @Page Language="C#" %> <% @Import Namespace="System" %> <% // String als Folge von Zeichen ausgeben string str = "Das ist ein Test"; for (int i=0;i < str.Length; i++) { // Chars indexer Response.Write(str[i].ToString()); } %>
In der ersten Zeile werden die für ASP.NET benötigten Direktiven (gekennzeichnet durch "@") deklariert. Zuerst die Definition der verwendeten Codesprachen (in diesem Fall C#) und dann die Definition des verwendeten Namespaces (hier "System"). Danach folgt die Deklaration der Stringvariable "str" samt Inhalt.
Mittels eines for Statements werden die einzelnen Buchstaben (Datentyp: char) des Strings über den Chars Indexer des String Objekts ausgeben. Da aber Response.Write Strings ausgibt, muß ich den char mit Hilfe der ToString Methode auf einen String rückumwandeln.
Etwas, das man als Programmierer oft macht ist Daten von einem Typ auf einen anderen zu konvertieren. Im Gegensatz zur 1 gibt es in der Beta 2 gibt es nur mehr Konvertierungsmethoden die auch mit Strings zu tun haben. (Fast) alles was man für Stringbehandlungen brauchen kann, wird von der String Klasse durch ihre Konvertierungsroutinen zur Verfügung gestellt:
ToCharArray | Gibt den String als Array von Buchstaben zurück (overloaded) | ToLower | Erstellt eine Kopie des Strings in Kleinbuchstaben (overloaded) |
ToString | Gibt die Instanz des Strings zurück |
ToUpper | Erstellt eine Kopie des Strings in Großbuchstaben (overloaded) |
Mit der Split Methode können Sie einen String, anhand bestimmter Separatoren aufteilen. Dies ist äquivalent zur Funktion Split in VBScript. Das folgende Beispiel verdeutlicht die Verwendung splittingipaddress.aspx:
<% @Page Language="C#" %> <% @Import Namespace="System" %> <% char[] chSplit = {'.'}; string[] arrIP = "192.168.1.105".Split(chSplit); // Ausgabe der Anzahl der gesplitteten Strings Response.Write(arrIP.Length.ToString()); %>
Wie man sieht, muß man an die Split Methode ein Array übergeben, was einem die Option eröffnet, mehrere Separationszeichen zu verwenden. Übrigens: der Code funktioniert wirklich, auch wenn es etwas komisch aussieht wenn man an einen String einen Funktionsaufruf anflanscht.
Ebenfalls ein sehr beliebtes Thema bei der Verwendung von Strings ist das Auffinden von einzelnen Zeichen beziehungsweise Zeichenketten in einem String. Anwendungsfälle wären zum Beispiel: Finden des letzten Backslashes ("\") in einem Pfad, das Auffinden des @-Zeichens in einer Emailadresse und vieles anderes mehr.
Und wie geht das mit der String-Klasse? Einfach. Man hat 2 Methoden names IndexOf und LastIndexOf, die zur Zeichen und Zeichenkettensuche geeignet sind.
Typ | Beschreibung |
---|---|
IndexOf | Gibt den Index des ersten Auftretens eines Zeichens oder Strings zurück (overloaded) |
LastIndexOf | Gibt den Index des letzten Auftretens eines Zeichens oder Strings zurück (overloaded) |
Das nun folgende Beispiel veranschaulicht die Verwendung der beiden Methoden:
<% @Page Language="C#" %> <% @Import Namespace="System.Text" %> <% string strTest = "Wahnsinn, der hat in Leoben Methode"; // findet die Position des "L" in Leoben int nIndex = strTest.IndexOf("Leoben"); // findet die Position des "d" in Methode int nIndex2 = strTest.LastIndexOf("de"); %>
Wie die Überschrift schon sagt, wird hier vorgestellt, wie man 2 Strings miteinander vergleicht. Dazu verwendet man die Compare Methode, die, wenn die beiden Strings ident sind, das Ergebnis 0 (die Zahl) liefert.
Der Sourcecode zum Beispiel comparison.aspx:
<% @Page Language="C#" %> <% @Import Namespace="System" %> <% string strA = "Leoben"; string strB = "Bad Ischl"; int nTest; nTest = String.Compare(strA,strB); //Ausgabe Response.Write("1. String: " + strA + "<br>"); Response.Write("2. String: " + strB + "<br>"); Response.Write("Die Strings sind gleich wenn Ergebnis = 0." + "<br>"); Response.Write("Ergebnis: " + nTest.ToString()); %>
Beachte: Hier wiederum nicht vergessen, daß das Response.Write Statement nur Strings ausgeben kann. Anyway: der Compiler meckert eh'.
Es gibt für VBScript Programmierer in der String Klasse alte Bekannte: die Methoden zum String Trimmen, allerdings um so einiges verändert:
Typ | Beschreibung |
---|---|
Trim | Scheidet die Leerzeichen eines Strings weg (overloaded) |
TrimEnd | Entfernt einen angegebenen String von Buchstaben vom Ende des Strings |
TrimStart | Entfernt einen angegebenen String von Buchstaben vom Anfang des Strings |
Hier das Beispiel zur Verwendung der TrimEnd Funktion (trimend.aspx):
<% @Page Language="C#" %> <% @Import Namespace="System" %> <% string strA = "Bad Ischl "; char[] ch2Trim = {' '}; string strB = strA.TrimEnd(ch2Trim); // Ausgabe - man sollte sich den Source der Ergebnisseite ansehen! Response.Write("String vorher:" + strA.ToString() + "<br>"); Response.Write("String nachher: " + strB.ToString() + "<br>"); %>
Warum sollte das eine große Hexerei sein? Viele Beispiele haben ja bereits das verwendet:
strTest = "hans" + " hansi";
Eine Alternative hierfür wäre die Verwendung der Concat Methode (StringConcat.aspx):
<% @Page Language="C#" %> <% @Import Namespace="System" %> <% string strA="Leoben", strB="Bad Ischl", strC="Bruck", strD; strD = String.Concat(strA,", ",strB,", ",strC); Response.Write(strD); %>
Der erste Ansatz funktioniert zwar auch, er ist allerdings heftig ineffizient, vor allem dann, wenn man mehr als nur zwei Anfügefunktionen durchführt (in einer Schleife zB). Warum, erkläre ich in Kürze, zuerst schauen wir uns den effizienten Weg an.
Der effiziente Weg ist die StringBuilder Klasse. Diese verfügt über die Methode Append, mit welcher man den internen Stringpuffer um den anzuhängenden String erweitert (in-place sozusagen). Damit arbeitet man schneller als mit dem + Operator, da dieser immer String Objekte erzeugt, kopiert und zerstört.
Das Beispiel zeigt, wie man mit der StringBuilder Klasse arbeitet.
<% @Page Language="C#" %> <% @Import Namespace="System.Text" %> <% StringBuilder strBuilder = new StringBuilder(""); // string strTest = new String(""); for (int i=1;i<=5;i++) { strBuilder.Append("Hello World<br>"); // strTest += "Hello world<br>"; // strTest = strTest + "Hello world<br>"; // strTest = strTest + new String("Hello world<br>"); // strTest = new String(strTest + new String("Hello world<br>")); } Response.Write(strBuilder.ToString()); %>
In den Kommentaren steht, was mit der String Klasse und dem + Operator passiert wäre. Die erste Zeile in der for Schleife zeigt das Statement, wie es der Programmierer geschrieben hätte. In jeder weiteren Zeile habe ich dann die vom Compiler implizit vorgenommenen Erweiterungen eingebaut. Und in der letzten Zeile sieht man dann sehr deutlich, warum Strings aneinanderfügen ineffizient ist: zwei String Objekte werden angelegt, und drei werden zerstört (inklusive dem originalen strTest).
Im Gegensatz dazu hat StringBuilder einen Puffer, der an die Größenbedürfnisse angepasst werden kann - auch für Lösch- und Einfügeoperationen.
Ich habe es bereits in der vorangegangen Sektion angesprochen - man kann im StringBuilder auch nach Belieben löschen und einfügen. Im folgenden Beispiel verwende ich Remove und Insert, um einen String zu modifizieren (removeandinsert.aspx):
<% @Page Language="C#" %> <% @Import Namespace="System.Text" %> <% string strTest = "Ich finde, Leoben ist eine schöne Stadt."; StringBuilder strBuilder = new StringBuilder(strTest); int nIndex = strTest.IndexOf("Leoben"); strBuilder.Remove(nIndex, "Leoben".Length); strBuilder.Insert(nIndex, "Bad Ischl"); // Ausgabe Response.Write(strBuilder.ToString()); %>
Das Wort "Leoben" wird in dem String "Ich finde, Leoben ist eine schöne Stadt." durch "Bad Ischl" ausgetauscht. Zuerst wird "Leoben" mit Hilfe von Remove gelöscht, und dann "Bad Ischl" mit Insert bei der Position des zuvor gelöschten Strings eingefügt.
Alternativ erhält man das gleiche Ergebnis mit dieser kürzeren Version (replace.aspx):
<% @Page Language="C#" %> <% @Import Namespace="System.Text" %> <% StringBuilder strBuilder = new StringBuilder("Ich finde, Leoben ist ein schöne Stadt."); // der folgende Befehl tauscht alle Strings "Leoben" aus strBuilder.Replace("Leoben", "Bad Ischl"); // Ausgabe des veränderten Strings Response.Write(strBuilder.ToString()); %>
Die angeführten Beispiele sollen Ihnen dabei helfen, bei der Stringbehandlung in C# möglichst schnell mit Ihren bisherigen Kenntnissen und Techniken aus anderen Programmiersprachen gleichzuziehen. In diesem Artikel habe ich Möglichkeiten gezeigt, wie man Strings partiell löschen, austauschen, kürzen und aufteilen kann - mit Hinblick auf die Praxis des täglichen Programmierens.
This printed page brought to you by AlphaSierraPapa
Klicken Sie hier, um den Download zu starten.
http://www.aspheute.com/code/20000803.zip
A Brief History of C#
http:/www.aspheute.com/artikel/20000713.htm
Deutsche Personalausweisnummern verifizieren
http:/www.aspheute.com/artikel/20020507.htm
Eine Klasse für sich - die .NET Zip Library
http:/www.aspheute.com/artikel/20011115.htm
On-the-fly Erstellung von vCard's
http:/www.aspheute.com/artikel/20020906.htm
Variable Parameterlisten in Funktionen
http:/www.aspheute.com/artikel/20020125.htm
Web Services 101 in ASP.NET
http:/www.aspheute.com/artikel/20010621.htm
Webseiten automatisiert scrapen, Teil 2
http:/www.aspheute.com/artikel/20010911.htm
WHOIS Abfragen a la .NET
http:/www.aspheute.com/artikel/20000825.htm
Zahl, Datum und Währung korrekt formatiert ausgeben
http:/www.aspheute.com/artikel/20020704.htm
©2000-2006 AspHeute.com
Alle Rechte vorbehalten. Der Inhalt dieser Seiten ist urheberrechtlich geschützt.
Eine Übernahme von Texten (auch nur auszugsweise) oder Graphiken bedarf unserer schriftlichen Zustimmung.