4. Häufig verwendete Klassen der Plattform .NET
Wir stellen hier einige Klassen der Plattform .NET vor, die auch für Anfänger von Interesse sind. Zunächst zeigen wir, wie man Informationen zu den Hunderten von verfügbaren Klassen erhält.
4.1. Hilfe bei SDK.NET suchen
4.1.1. wincv
Wenn nur das SDK und nicht Visual Studio.NET installiert wurde, kann das Programm wincv.exe verwendet werden, das sich normalerweise im SDK-Verzeichnis befindet, zum Beispiel unter C:\Program Files\Microsoft Visual Studio.NET 2003\SDK\v1.1. Beim Starten dieses Dienstprogramms wird folgende Benutzeroberfläche angezeigt:
![]() |
Man gibt unter (1) den Namen der gewünschten Klasse ein. Daraufhin werden unter (2) verschiedene mögliche Themen angezeigt. Man wählt das passende aus und erhält das Ergebnis unter (3), in diesem Fall die Klasse HashTable. Diese Methode eignet sich, wenn man den Namen der gesuchten Klasse kennt. Möchte man die Liste der von der .NET oder die Datei HTML StartHere.htm verwenden, die sich ebenfalls direkt im Installationsordner von SSK.Net befindet, zum Beispiel C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.

Über den Link „.NET Framework SDK Dokumentation“ erhalten Sie einen Überblick über die Klassen „.NET“:

Dort folgen wir dem Link [Bibliothèque de classes]. Dort finden wir die Liste aller Klassen von .NET:

Folgen wir zum Beispiel dem Link System.Collections. Dieser Namensraum umfasst verschiedene Klassen, die Sammlungen implementieren, darunter die Klasse HashTable:

Folgen wir dem untenstehenden Link HashTable:

Wir gelangen auf die folgende Seite:

Beachten Sie unten die Position des Mauszeigers. Er zeigt auf einen Link, über den die gewünschte Sprache ausgewählt werden kann, in diesem Fall Visual Basic.
Dort finden wir den Prototyp der Klasse sowie Anwendungsbeispiele. Folgen wir dem untenstehenden Link [Hashtable, membres]:

Man erhält die vollständige Beschreibung der Klasse:

Diese Methode eignet sich am besten, um sich mit SDK und seinen Klassen vertraut zu machen. Das Tool WinCV erweist sich als nützlich, wenn man die Klasse bereits ein wenig kennt und einige ihrer Mitglieder vergessen hat. Mit WinCV lassen sich die Klasse und ihre Mitglieder dann schnell wiederfinden.
4.2. Hilfe zu Klassen mit VS.NET suchen
Hier geben wir einige Hinweise, wie Sie mit Visual Studio.NET Hilfe finden können
4.2.1. Option „Hilfe“
Wählen wir die Option [?] aus dem Menü.

Es erscheint das folgende Fenster:

In der Dropdown-Liste kann man einen Hilfefilter auswählen. Hier wählen wir den Filter [Visual Basic].

Zwei Hilfestellungen sind nützlich:
- die Hilfe zur Sprache VB.NET selbst (Syntax)
- die Hilfe zu den classes.NET, die von der Sprache VB.NET verwendet werden können
Die Hilfe zur Sprache VB.NET ist über [Visual Studio.NET/Visual Basic et Visual C#/Reference/Visual Basic] zugänglich:

Man gelangt zur folgenden Hilfeseite:

Von dort aus bieten die verschiedenen Unterrubriken Hilfe zu verschiedenen Themen von VB.NET. Beachten Sie insbesondere die Tutorials von VB.NET:

Um Zugriff auf die verschiedenen Klassen der Plattform .NET zu erhalten, wählen wir die Hilfe [Visual Studio.NET/.NET Framework].

Von besonderem Interesse ist dabei der Abschnitt [Référence/Bibliothèque de classes]:

Nehmen wir an, wir interessieren uns für die Klasse [ArrayList]. Sie befindet sich im Namensraum [System.Collections]. Das muss man wissen, andernfalls sollte man die im Folgenden beschriebene Suchmethode bevorzugen. Man erhält folgende Hilfe:

Der Link [ArrayList, classe] bietet einen Überblick über die Klasse:

Diese Art von Seite gibt es für alle Klassen. Sie bietet eine Zusammenfassung der Klasse mit Beispielen. Für eine Beschreibung der Klassenelemente folgt man dem Link [ArrayList, membres]:

4.2.2. Hilfe/Index

Mit der Option [Aide/index] lässt sich die Hilfe gezielter suchen als mit der vorherigen Option. Geben Sie einfach das gesuchte Stichwort ein:

Der Vorteil dieser Methode gegenüber der vorherigen besteht darin, dass man nicht wissen muss, wo sich das Gesuchte im Hilfesystem befindet. Diese Methode ist wahrscheinlich die bevorzugte Wahl für eine gezielte Suche, während die andere Methode eher dazu geeignet ist, das gesamte Angebot der Hilfe zu erkunden.
4.3. Die Klasse „String“
Die Klasse „String“ verfügt über zahlreiche Eigenschaften und Methoden. Hier sind einige davon:
Anzahl der Zeichen in der Zeichenkette | |
Standardmäßig indizierte Eigenschaft. [String].Chars(i) ist das Zeichen Nr. i der Zeichenkette | |
gibt „wahr“ zurück, wenn die Zeichenkette mit „value“ endet | |
gibt „wahr“ zurück, wenn die Zeichenfolge mit dem Wert beginnt | |
gibt „wahr“ zurück, wenn die Zeichenfolge mit „value“ übereinstimmt | |
gibt die erste Position der Zeichenfolge „value“ in der Zeichenfolge zurück – die Suche beginnt ab Zeichen Nr. 0 | |
gibt die erste Position der Zeichenfolge „value“ in der Zeichenfolge zurück – die Suche beginnt ab Zeichen Nr. startIndex | |
Klassenmethode – gibt eine Zeichenkette zurück, die das Ergebnis der Verkettung der Werte des Arrays „value“ mit dem Trennzeichen „separator“ ist | |
Gibt eine Kopie der aktuellen Zeichenkette zurück, in der das Zeichen oldChar durch das Zeichen newChar ersetzt wurde | |
Die Zeichenkette wird als eine Folge von Feldern betrachtet, die durch die in der Tabelle „separator“ enthaltenen Zeichen getrennt sind. Das Ergebnis ist ein Array dieser Felder | |
Teilzeichenfolge der aktuellen Zeichenfolge, beginnend an der Position startIndex und mit einer Länge von length Zeichen | |
wandelt die aktuelle Zeichenkette in Kleinbuchstaben um | |
wandelt die aktuelle Zeichenfolge in Großbuchstaben um | |
entfernt die führenden und abschließenden Leerzeichen aus der aktuellen Zeichenkette |
Eine Zeichenkette C kann als Zeichenarray betrachtet werden. Somit
- ist C.Chars(i) das i-te Zeichen von C
- C.Length ist die Anzahl der Zeichen in C
Betrachten wir das folgende Beispiel:
' Optionen
Option Strict On
Option Explicit On
' Namensräume
Imports System
Module test
Sub Main()
Dim uneChaine As String = "l'oiseau vole au-dessus des nuages"
affiche("uneChaine=" + uneChaine)
affiche("uneChaine.Length=" & uneChaine.Length)
affiche("chaine[10]=" + uneChaine.Chars(10))
affiche("uneChaine.IndexOf(""vole"")=" & uneChaine.IndexOf("vole"))
affiche("uneChaine.IndexOf(""x"")=" & uneChaine.IndexOf("x"))
affiche("uneChaine.LastIndexOf('a')=" & uneChaine.LastIndexOf("a"c))
affiche("uneChaine.LastIndexOf('x')=" & uneChaine.LastIndexOf("x"c))
affiche("uneChaine.Substring(4,7)=" + uneChaine.Substring(4, 7))
affiche("uneChaine.ToUpper()=" + uneChaine.ToUpper())
affiche("uneChaine.ToLower()=" + uneChaine.ToLower())
affiche("uneChaine.Replace('a','A')=" + uneChaine.Replace("a"c, "A"c))
Dim champs As String() = uneChaine.Split(Nothing)
Dim i As Integer
For i = 0 To champs.Length - 1
affiche("champs[" & i & "]=[" & champs(i) & "]")
Next i
affiche("Join("":"",champs)=" + System.String.Join(":", champs))
affiche("("" abc "").Trim()=[" + " abc ".Trim() + "]")
End Sub
' Anzeige
Sub affiche(ByVal msg As [String])
' zeigt Meldung an
Console.Out.WriteLine(msg)
End Sub
End Module
Die Ausführung liefert folgende Ergebnisse:
dos>vbc string1.vb
dos>string1
uneChaine=l'oiseau vole au-dessus des nuages
uneChaine.Length=34
chaine[10]=o
uneChaine.IndexOf("vole")=9
uneChaine.IndexOf("x")=-1
uneChaine.LastIndexOf('a')=30
uneChaine.LastIndexOf('x')=-1
uneChaine.Substring(4,7)=seau vo
uneChaine.ToUpper()=L'OISEAU VOLE AU-DESSUS DES NUAGES
uneChaine.ToLower()=l'oiseau vole au-dessus des nuages
uneChaine.Replace('a','A')=l'oiseAu vole Au-dessus des nuAges
champs[0]=[l'oiseau]
champs[1]=[vole]
champs[2]=[au-dessus]
champs[3]=[des]
champs[4]=[nuages]
Join(":",champs)=l'oiseau:vole:au-dessus:des:nuages
(" abc ").Trim()=[abc]
Betrachten wir ein neues Beispiel:
' Optionen
Option Strict On
Option Explicit On
' Namensräume
Imports System
Module string2
Sub Main()
' die zu analysierende Zeile
Dim ligne As String = "un:deux::trois:"
' Feldtrennzeichen
Dim séparateurs() As Char = {":"c}
' Aufteilung
Dim champs As String() = ligne.Split(séparateurs)
Dim i As Integer
For i = 0 To champs.Length - 1
Console.Out.WriteLine(("Champs[" & i & "]=" & champs(i)))
Next i
' Join
Console.Out.WriteLine(("join=[" + System.String.Join(":", champs) + "]"))
End Sub
End Module
und die Ausführungsergebnisse:
Mit der Methode „Split“ der Klasse String lassen sich die Felder einer Zeichenkette in ein Array zerlegen. Die Definition der hier verwendeten Methode lautet wie folgt:
Zeichenarray. Diese Zeichen stellen die Trennzeichen dar, die zur Trennung der Felder der Zeichenkette verwendet werden. Wenn die Zeichenkette also [champ1, champ2, champ3] lautet, kann man separator=new char() {","c} verwenden. Ist das Trennzeichen eine Folge von Leerzeichen, verwendet man separator=nothing. | |
Array von Zeichenketten, wobei jedes Element ein Feld der Zeichenkette ist. |
Die Methode Join ist eine statische Methode der Klasse *String*:
Zeichenfolgen-Array | |
eine Zeichenkette, die als Feldtrennzeichen dient | |
eine Zeichenkette, die aus der Verkettung der Elemente des Arrays value besteht, getrennt durch die Zeichenkette separator. |
4.4. Die Klasse „Array“
Die Klasse „Array“ implementiert ein Array. In unserem Beispiel verwenden wir die folgenden Eigenschaften und Methoden:
Eigenschaft – Anzahl der Elemente des Arrays | |
Klassenmethode – gibt die Position von value im sortierten Array array zurück – sucht ab der Position index und mit length Elementen | |
Klassenmethode – kopiert Elemente von length aus sourceArray in destinationArray – dabei wird destinationArray angelegt | |
Klassenmethode – sortiert das Array array – dieses muss einen Datentyp enthalten, der über eine Standard-Sortierfunktion verfügt (Zeichenketten, Zahlen). |
Das folgende Programm veranschaulicht die Verwendung der Klasse Array:
' Optionen
Option Strict On
Option Explicit On
' Namensräume
Imports System
Module test
Sub Main()
' Einlesen von per Tastatur eingegebenen Array-Elementen
Dim terminé As [Boolean] = False
Dim i As Integer = 0
Dim éléments1 As Double() = Nothing
Dim éléments2 As Double() = Nothing
Dim élément As Double = 0
Dim réponse As String = Nothing
Dim erreur As [Boolean] = False
While Not terminé
' Frage
Console.Out.Write(("Elément (réel) " & i & " du tableau (rien pour terminer) : "))
' Antwort einlesen
réponse = Console.ReadLine().Trim()
' Ende der Eingabe bei leerer Zeichenkette
If réponse.Equals("") Then
Exit While
End If
' Überprüfung der Eingabe
Try
élément = [Double].Parse(réponse)
erreur = False
Catch
Console.Error.WriteLine("Saisie incorrecte, recommencez")
erreur = True
End Try
' wenn kein Fehler vorliegt
If Not erreur Then
' neues Array zur Aufnahme des neuen Elements
éléments2 = New Double(i) {}
' Altes Array in neues Array kopieren
If i <> 0 Then
Array.Copy(éléments1, éléments2, i)
End If
' Das neue Array wird zum alten Array
éléments1 = éléments2
' Das neue Array wird nicht mehr benötigt
éléments2 = Nothing
' Einfügen eines neuen Elements
éléments1(i) = élément
' ein weiteres Element im Array
i += 1
End If
End While
' Anzeige des unsortierten Arrays
System.Console.Out.WriteLine("Tableau non trié")
For i = 0 To éléments1.Length - 1
Console.Out.WriteLine(("éléments[" & i & "]=" & éléments1(i)))
Next i
' Sortierung der Tabelle
System.Array.Sort(éléments1)
' Anzeige der sortierten Tabelle
System.Console.Out.WriteLine("Tableau trié")
For i = 0 To éléments1.Length - 1
Console.Out.WriteLine(("éléments[" & i & "]=" & éléments1(i)))
Next i
' Suche
While Not terminé
' Frage
Console.Out.Write("Elément cherché (rien pour arrêter) : ")
' Antwort vorlesen und überprüfen
réponse = Console.ReadLine().Trim()
' Fertig?
If réponse.Equals("") Then
Exit While
End If
' Überprüfung
Try
élément = [Double].Parse(réponse)
erreur = False
Catch
Console.Error.WriteLine("Saisie incorrecte, recommencez")
erreur = True
End Try
' Wenn kein Fehler
If Not erreur Then
' Das Element wird im sortierten Array gesucht
i = System.Array.BinarySearch(éléments1, 0, éléments1.Length, élément)
' Anzeige der Antwort
If i >= 0 Then
Console.Out.WriteLine(("Trouvé en position " & i))
Else
Console.Out.WriteLine("Pas dans le tableau")
End If
End If
End While
End Sub
End Module
Die Bildschirmausgabe sieht wie folgt aus:
Elément (réel) 0 du tableau (rien pour terminer) : 10,4
Elément (réel) 1 du tableau (rien pour terminer) : 5,2
Elément (réel) 2 du tableau (rien pour terminer) : 8,7
Elément (réel) 3 du tableau (rien pour terminer) : 3,6
Elément (réel) 4 du tableau (rien pour terminer) :
Tableau non trié
éléments[0]=10,4
éléments[1]=5,2
éléments[2]=8,7
éléments[3]=3,6
Tableau trié
éléments[0]=3,6
éléments[1]=5,2
éléments[2]=8,7
éléments[3]=10,4
Elément cherché (rien pour arrêter) : 8,7
Trouvé en position 2
Elément cherché (rien pour arrêter) : 11
Pas dans le tableau
Elément cherché (rien pour arrêter) : a
Saisie incorrecte, recommencez
Elément cherché (rien pour arrêter) :
Der erste Teil des Programms erstellt ein Array aus numerischen Daten, die über die Tastatur eingegeben werden. Die Größe des Arrays kann nicht im Voraus festgelegt werden, da die Anzahl der Elemente, die der Benutzer eingeben wird, nicht bekannt ist. Daher wird mit zwei Arrays gearbeitet: éléments1 und éléments2.
' neues Array zur Aufnahme des neuen Elements
éléments2 = New Double(i) {}
' Altes Array in neues Array kopieren
If i <> 0 Then
Array.Copy(éléments1, éléments2, i)
End If
' Das neue Array wird zum alten Array
éléments1 = éléments2
' Das neue Array wird nicht mehr benötigt
éléments2 = Nothing
' Einfügen eines neuen Elements
éléments1(i) = élément
' ein weiteres Element in der Tabelle
i += 1
Die Tabelle éléments1 enthält die aktuell eingegebenen Werte. Wenn der Benutzer einen neuen Wert hinzufügt, wird eine Tabelle éléments2 angelegt, die ein Element mehr enthält als éléments1, der Inhalt von éléments1 wird in éléments2 (Array.Copy) kopiert, man lässt éléments1 auf éléments2 „verweisen“ und fügt schließlich das neue Element zu éléments1 hinzu. Dies ist ein komplexer Vorgang, der vereinfacht werden kann, wenn anstelle eines Arrays fester Größe (Array) ein Array variabler Größe (ArrayList) verwendet wird.
Das Array wird mit der Methode Array.Sort sortiert. Diese Methode kann mit verschiedenen Parametern aufgerufen werden, die die Sortierregeln festlegen. Ohne Parameter erfolgt standardmäßig eine Sortierung in aufsteigender Reihenfolge. Schließlich ermöglicht die Methode Array.BinarySearch die Suche nach einem Element in einem sortierten Array.
4.5. Die Klasse ArrayList
Die Klasse ArrayList ermöglicht die Implementierung von Arrays mit variabler Größe während der Programmausführung, was mit der vorherigen Klasse Array nicht möglich ist. Hier sind einige der gängigen Eigenschaften und Methoden:
Erstellt eine leere Liste | |
Anzahl der Elemente in der Sammlung | |
fügt das Objekt „value“ am Ende der Sammlung hinzu | |
löscht die Liste | |
Index des Objekts „value“ in der Liste oder -1, falls es nicht vorhanden ist | |
ebenso, jedoch beginnend mit dem Element Nr. startIndex | |
ebenso, gibt jedoch den Index des letzten Vorkommens von „value“ in der Liste zurück | |
ebenso, sucht jedoch ab dem Element Nr. startIndex | |
Entferne das Objekt „obj“, falls es in der Liste vorhanden ist | |
Entfernt das Element mit dem Index aus der Liste | |
Gibt die Position des Objekts „value“ in der Liste zurück oder -1, wenn es nicht vorhanden ist. Die Liste muss sortiert sein | |
sortiert die Liste. Diese muss Objekte enthalten, die eine vordefinierte Reihenfolge aufweisen (Zeichenketten, Zahlen) | |
sortiert die Liste gemäß der durch die Funktion „vergleichen“ festgelegten Reihenfolge |
Nehmen wir das Beispiel mit Objekten vom Typ Array noch einmal auf und wenden wir es auf Objekte vom Typ ArrayList an:
' Optionen
Option Strict On
Option Explicit On
' Namensräume
Imports System
Imports System.Collections
Module test
Sub Main()
' Auslesen der per Tastatur eingegebenen Array-Elemente
Dim terminé As [Boolean] = False
Dim i As Integer = 0
Dim éléments As New ArrayList
Dim élément As Double = 0
Dim réponse As String = Nothing
Dim erreur As [Boolean] = False
While Not terminé
' Frage
Console.Out.Write(("Elément (réel) " & i & " du tableau (rien pour terminer) : "))
' Antwort auslesen
réponse = Console.ReadLine().Trim()
' Eingabe beenden, wenn Zeichenfolge leer ist
If réponse.Equals("") Then
Exit While
End If
' Eingabeprüfung
Try
élément = Double.Parse(réponse)
erreur = False
Catch
Console.Error.WriteLine("Saisie incorrecte, recommencez")
erreur = True
End Try
' wenn kein Fehler vorliegt
If Not erreur Then
' ein weiteres Element in das Array
éléments.Add(élément)
End If
End While
' Anzeige des unsortierten Arrays
System.Console.Out.WriteLine("Tableau non trié")
For i = 0 To éléments.Count - 1
Console.Out.WriteLine(("éléments[" & i & "]=" & éléments(i).ToString))
Next i ' tri du tableau
éléments.Sort()
' Anzeige des sortierten Arrays
System.Console.Out.WriteLine("Tableau trié")
For i = 0 To éléments.Count - 1
Console.Out.WriteLine(("éléments[" & i & "]=" & éléments(i).ToString))
Next i
' Suche
While Not terminé
' Frage
Console.Out.Write("Elément cherché (rien pour arrêter) : ")
' Antwort lesen und überprüfen
réponse = Console.ReadLine().Trim()
' Fertig?
If réponse.Equals("") Then
Exit While
End If
' Überprüfung
Try
élément = [Double].Parse(réponse)
erreur = False
Catch
Console.Error.WriteLine("Saisie incorrecte, recommencez")
erreur = True
End Try
' Wenn kein Fehler
If Not erreur Then
' Das Element wird im sortierten Array gesucht
i = éléments.BinarySearch(élément)
' Anzeige der Antwort
If i >= 0 Then
Console.Out.WriteLine(("Trouvé en position " & i))
Else
Console.Out.WriteLine("Pas dans le tableau")
End If
End If
End While
End Sub
End Module
Die Ausführungsergebnisse lauten wie folgt:
Elément (réel) 0 du tableau (rien pour terminer) : 10,4
Elément (réel) 0 du tableau (rien pour terminer) : 5,2
Elément (réel) 0 du tableau (rien pour terminer) : a
Saisie incorrecte, recommencez
Elément (réel) 0 du tableau (rien pour terminer) : 3,7
Elément (réel) 0 du tableau (rien pour terminer) : 15
Elément (réel) 0 du tableau (rien pour terminer) :
Tableau non trié
éléments[0]=10,4
éléments[1]=5,2
éléments[2]=3,7
éléments[3]=15
Tableau trié
éléments[0]=3,7
éléments[1]=5,2
éléments[2]=10,4
éléments[3]=15
Elément cherché (rien pour arrêter) : a
Saisie incorrecte, recommencez
Elément cherché (rien pour arrêter) : 15
Trouvé en position 3
Elément cherché (rien pour arrêter) : 1
Pas dans le tableau
Elément cherché (rien pour arrêter) :
4.6. Die Klasse „Hashtable“
Mit der Klasse Hashtable lässt sich ein Wörterbuch implementieren. Ein Wörterbuch kann man sich als zweispaltiges Array vorstellen:
![]() |
Die Schlüssel sind eindeutig, c.a.d, d. h., es kann keine zwei identischen Schlüssel geben. Die wichtigsten Methoden und Eigenschaften der Klasse „Hashtable“ sind die folgenden:
Erstellt ein leeres Wörterbuch | |
Fügt eine Zeile (Schlüssel, Wert) in das Wörterbuch ein, wobei Schlüssel und Wert Objektreferenzen sind. | |
entfernt den Eintrag mit dem Schlüssel „key“ aus dem Wörterbuch | |
leert das Wörterbuch | |
Gibt „true“ zurück, wenn der Schlüssel „key“ im Wörterbuch enthalten ist. | |
| gibt „true“ zurück, wenn der Wert „value“ im Wörterbuch enthalten ist. |
Eigenschaft: Anzahl der Elemente im Wörterbuch (Schlüssel, Wert) | |
Eigenschaft: Sammlung der Schlüssel des Wörterbuchs | |
Eigenschaft: Sammlung der Werte des Wörterbuchs | |
indizierte Eigenschaft: ermöglicht es, den einem Schlüssel „key“ zugeordneten Wert abzurufen oder festzulegen |
Betrachten wir das folgende Beispielprogramm:
' Optionen
Option Strict On
Option Explicit On
' Namensräume
Imports System
Imports System.Collections
Module test
Sub Main()
Dim liste() As [String] = {"jean:20", "paul:18", "mélanie:10", "violette:15"}
Dim i As Integer
Dim champs As [String]() = Nothing
Dim séparateurs() As Char = {":"c}
' Befüllen des Wörterbuchs
Dim dico As New Hashtable
For i = 0 To liste.Length - 1
champs = liste(i).Split(séparateurs)
dico.Add(champs(0), champs(1))
Next i
' Anzahl der Elemente im Wörterbuch
Console.Out.WriteLine(("Le dictionnaire a " & dico.Count & " éléments"))
' Liste der Schlüssel
Console.Out.WriteLine("[Liste des clés]")
Dim clés As IEnumerator = dico.Keys.GetEnumerator()
While clés.MoveNext()
Console.Out.WriteLine(clés.Current)
End While
' Liste der Werte
Console.Out.WriteLine("[Liste des valeurs]")
Dim valeurs As IEnumerator = dico.Values.GetEnumerator()
While valeurs.MoveNext()
Console.Out.WriteLine(valeurs.Current)
End While
' Liste der Schlüssel und Werte
Console.Out.WriteLine("[Liste des clés & valeurs]")
clés.Reset()
While clés.MoveNext()
Console.Out.WriteLine(("clé=" & clés.Current.ToString & " valeur=" & dico(clés.Current).ToString))
End While
' Der Schlüssel „paul“ wird gelöscht
Console.Out.WriteLine("[Suppression d'une clé]")
dico.Remove("paul")
' Liste der Schlüssel und Werte
Console.Out.WriteLine("[Liste des clés & valeurs]")
clés = dico.Keys.GetEnumerator()
While clés.MoveNext()
Console.Out.WriteLine(("clé=" & clés.Current.ToString & " valeur=" & dico(clés.Current).ToString))
End While
' Suche im Wörterbuch
Dim nomCherché As [String] = Nothing
Console.Out.Write("Nom recherché (rien pour arrêter) : ")
nomCherché = Console.ReadLine().Trim()
Dim value As [Object] = Nothing
While Not nomCherché.Equals("")
If dico.ContainsKey(nomCherché) Then
value = dico(nomCherché)
Console.Out.WriteLine((nomCherché + "," + CType(value, [String])))
Else
Console.Out.WriteLine(("Nom " + nomCherché + " inconnu"))
End If
' nächste Suche
Console.Out.Write("Nom recherché (rien pour arrêter) : ")
nomCherché = Console.ReadLine().Trim()
End While
End Sub
End Module
Die Ausführungsergebnisse lauten wie folgt:
Le dictionnaire a 4 éléments
[Liste des clés]
mélanie
paul
violette
jean
[Liste des valeurs]
10
18
15
20
[Liste des clés & valeurs]
clé=mélanie valeur=10
clé=paul valeur=18
clé=violette valeur=15
clé=jean valeur=20
[Suppression d'une clé]
[Liste des clés & valeurs]
clé=mélanie valeur=10
clé=violette valeur=15
clé=jean valeur=20
Nom recherché (rien pour arrêter) : paul
Nom paul inconnu
Nom recherché (rien pour arrêter) : mélanie
mélanie,10
Nom recherché (rien pour arrêter) :
Das Programm verwendet außerdem ein Objekt vom Typ IEnumerator, um die Schlüssel- und Wertesammlungen des Wörterbuchs vom Typ ICollection zu durchlaufen (siehe oben die Eigenschaften „Keys“ und „Values“). Eine Sammlung ist eine Gruppe von Objekten, die durchlaufen werden kann. Die Schnittstelle ICollection ist wie folgt definiert:

Die Eigenschaft Count ermöglicht es uns, die Anzahl der Elemente der Sammlung zu ermitteln. Die Schnittstelle ICollection leitet sich von der Schnittstelle IEnumerable ab:

Diese Schnittstelle verfügt nur über eine Methode, GetEnumerator, mit der wir ein Objekt vom Typ IEnumerator abrufen können:

Die Methode GetEnumerator() einer Sammlung vom Typ ICollection ermöglicht es uns, die Sammlung mit den folgenden Methoden zu durchlaufen:
Springt zum nächsten Element der Sammlung. Gibt „true“ zurück, wenn dieses Element vorhanden ist, andernfalls „false“. Der erste Aufruf von MoveNext springt zum ersten Element. Das „aktuelle“ Element der Sammlung ist dann in der Eigenschaft Current des Enumerators verfügbar | |
Eigenschaft: aktuelles Element der Sammlung | |
setzt den Iterator an den Anfang der Sammlung zurück, c.a.d, vor das erste Element. |
Die Struktur für die Iteration über die Elemente einer Sammlung (ICollection) in C sieht daher wie folgt aus:
' Sammlung definieren
dim C as ICollection C=...
' Enumerator für diese Sammlung abrufen
dim itérateur as IEnumerator=C.GetEnumerator();
' die Sammlung mit diesem Enumerator durchlaufen
while(itérateur.MoveNext())
' Es gibt ein aktuelles Element
' itérateur.Current auswerten
end while
4.7. Die Klasse StreamReader
Die Klasse StreamReader ermöglicht das Lesen des Inhalts einer Datei. Hier sind einige ihrer Eigenschaften und Methoden:
Öffnet einen Datenstrom aus der Datei „path“. Wenn diese nicht existiert, wird eine Ausnahme ausgelöst | |
schließt den Datenstrom | |
liest eine Zeile aus dem geöffneten Stream | |
liest den Rest des Streams ab der aktuellen Position |
Hier ein Beispiel:
' Optionen
Option Strict On
Option Explicit On
' Namensräume
Imports System
Imports System.Collections
Imports System.IO
Module test
Sub Main()
Dim ligne As String = Nothing
Dim fluxInfos As StreamReader = Nothing
' Inhalt der Datei lesen
Try
fluxInfos = New StreamReader("infos.txt")
ligne = fluxInfos.ReadLine()
While Not (ligne Is Nothing)
System.Console.Out.WriteLine(ligne)
ligne = fluxInfos.ReadLine()
End While
Catch e As Exception
System.Console.Error.WriteLine("L'erreur suivante s'est produite : " & e.ToString)
Finally
Try
fluxInfos.Close()
Catch
End Try
End Try
End Sub
End Module
und die Ausführungsergebnisse:
dos>more infos.txt
12620:0:0
13190:0,05:631
15640:0,1:1290,5
24740:0,15:2072,5
31810:0,2:3309,5
39970:0,25:4900
48360:0,3:6898,5
55790:0,35:9316,5
92970:0,4:12106
127860:0,45:16754,5
151250:0,5:23147,5
172040:0,55:30710
195000:0,6:39312
0:0,65:49062
dos>file1
12620:0:0
13190:0,05:631
15640:0,1:1290,5
24740:0,15:2072,5
31810:0,2:3309,5
39970:0,25:4900
48360:0,3:6898,5
55790:0,35:9316,5
92970:0,4:12106
127860:0,45:16754,5
151250:0,5:23147,5
172040:0,55:30710
195000:0,6:39312
0:0,65:49062
4.8. Die Klasse StreamWriter
Die Klasse StreamWriter ermöglicht das Schreiben in eine Datei. Hier sind einige ihrer Eigenschaften und Methoden:
Öffnet einen Schreibstrom aus der Datei „path“. Es wird eine Ausnahme ausgelöst, wenn dieser nicht erstellt werden kann | |
Ist der Wert „wahr“, erfolgt das Schreiben in den Stream ohne Zwischenspeicherung; andernfalls erfolgt das Schreiben nicht sofort: Zunächst wird in einen Puffer geschrieben, und erst wenn dieser voll ist, in den Stream. Standardmäßig wird der gepufferte Modus verwendet. Dieser eignet sich gut für Dateistreams, in der Regel jedoch nicht für Netzwerkstreams. | |
um das von der Methode WriteLine zu verwendende Zeilenendezeichen festzulegen oder zu ermitteln | |
schließt den Stream | |
schreibt eine Zeile in den Schreib-Stream | |
schreibt den Puffer in den Stream |
Betrachten wir das folgende Beispiel:
' Optionen
Option Strict On
Option Explicit On
' Namensräume
Imports System
Imports System.Collections
Imports System.IO
Module test
Sub Main()
Dim ligne As String = Nothing ' une ligne de texte
Dim fluxInfos As StreamWriter = Nothing ' le fichier texte
Try
' Erstellung der Textdatei
fluxInfos = New StreamWriter("infos.txt")
' Einlesen der über die Tastatur eingegebenen Zeile
Console.Out.Write("ligne (rien pour arrêter) : ")
ligne = Console.In.ReadLine().Trim()
' Schleife, solange die eingegebene Zeile nicht leer ist
While ligne <> ""
' Zeile in Textdatei schreiben
fluxInfos.WriteLine(ligne)
' Lesen einer neuen Zeile von der Tastatur
Console.Out.Write("ligne (rien pour arrêter) : ")
ligne = Console.In.ReadLine().Trim()
End While
Catch e As Exception
System.Console.Error.WriteLine("L'erreur suivante s'est produite : " & e.ToString)
Finally
' Datei schließen
Try
fluxInfos.Close()
Catch
End Try
End Try
End Sub
End Module
und die Ausführungsergebnisse:
dos>file2
ligne (rien pour arrêter) : ligne1
ligne (rien pour arrêter) : ligne2
ligne (rien pour arrêter) : ligne3
ligne (rien pour arrêter) :
dos>more infos.txt
ligne1
ligne2
ligne3
4.9. Die Klasse „Regex“
Die Klasse Regex ermöglicht die Verwendung regulärer Ausdrücke. Mit diesen lässt sich das Format einer Zeichenkette überprüfen. So kann beispielsweise überprüft werden, ob eine Zeichenkette, die ein Datum darstellt, tatsächlich im Format TT/MM/JJ vorliegt. Dazu wird ein Muster verwendet und die Zeichenkette mit diesem Muster verglichen. In diesem Beispiel müssen j, m und a also Ziffern sein. Das Muster für ein gültiges Datumsformat lautet dann „\d\d/\d\d/\d\d“, wobei das Symbol \d für eine Ziffer steht. Die folgenden Symbole können in einem Muster verwendet werden (Microsoft-Dokumentation):
Beschreibung | |
Markiert das folgende Zeichen als Sonderzeichen oder Literal. Beispielsweise entspricht „n“ dem Zeichen „n“. „\n“ entspricht einem Zeilenumbruch. Die Sequenz „\\“ entspricht „\“, während „\("“ dem Zeichen „(“ entspricht. | |
Entspricht dem Beginn der Eingabe. | |
Entspricht dem Ende der Eingabe. | |
Entspricht dem vorhergehenden Zeichen nullmal oder mehrmals. So entspricht „zo*“ sowohl „z“ als auch „zoo“. | |
Entspricht dem vorhergehenden Zeichen ein- oder mehrmals. So entspricht „zo+“ beispielsweise „zoo“, aber nicht „z“. | |
Entspricht dem vorhergehenden Zeichen null- oder einmal. Beispielsweise entspricht „a?ve?“ dem Zeichen „ve“ in „lever“. | |
Entspricht einem beliebigen einzelnen Zeichen, mit Ausnahme des Zeilenumbruchzeichens. | |
| Sucht nach modèle und speichert die Übereinstimmung. Die entsprechende Teilzeichenfolge kann mithilfe von Item [0]...[n] aus der erhaltenen Matches-Sammlung extrahiert werden. Um Übereinstimmungen mit Zeichen in Klammern ( ) zu finden, verwenden Sie „\(“ oder „\)“. |
| Entspricht entweder x oder y. Beispielsweise entspricht „z|foot“ entweder „z“ oder „foot“. „(z|f)oo“ entspricht entweder „zoo“ oder „foo“. |
| n ist eine nicht-negative ganze Zahl. Entspricht genau dem n-fachen des Zeichens. Beispielsweise entspricht „o{2}“ nicht dem „o“ in „Bob“, sondern den ersten beiden „o“ in „fooooot“. |
| n ist eine nicht-negative ganze Zahl. Entspricht mindestens n-mal dem Zeichen. Beispielsweise entspricht „o{2,}“ nicht dem „o“ in „Bob“, sondern allen „o“ in „fooooot“. „o{1,}“ entspricht „o+“ und „o{0,}“ entspricht „o*“. |
| m und n sind nicht-negative ganze Zahlen. Entspricht mindestens n und höchstens m Mal dem Zeichen. Beispielsweise entspricht „o{1,3}“ den ersten drei „o“ in „foooooot“ und „o{0,1}“ entspricht „o?“. |
| Zeichensatz. Entspricht einem der angegebenen Zeichen. Beispielsweise entspricht „[abc]“ dem Zeichen „a“ in „plat“. |
| Negativer Zeichensatz. Entspricht jedem nicht angegebenen Zeichen. Beispielsweise entspricht „[^abc]“ dem Zeichen „p“ in „plat“. |
| Zeichenbereich. Entspricht jedem Zeichen in der angegebenen Zeichenfolge. Beispielsweise entspricht „[a-z]“ jedem Kleinbuchstaben zwischen „a“ und „z“. |
| Negativer Zeichenbereich. Entspricht jedem Zeichen, das nicht in der angegebenen Zeichenfolge enthalten ist. Beispielsweise entspricht „[^m-z]“ jedem Zeichen, das nicht zwischen „m“ und „z“ liegt. |
Entspricht einer Grenze, die ein Wort darstellt, d. h. der Position zwischen einem Wort und einem Leerzeichen. Beispielsweise entspricht „er\b“ dem Wort „er“ in „lever“, nicht jedoch dem Wort „er“ in „verbe“. | |
Entspricht einer Grenze, die kein Wort darstellt. „en*t\B“ entspricht „ent“ in „bien entendu“. | |
Entspricht einem Zeichen, das eine Ziffer darstellt. Entspricht [0-9]. | |
Entspricht einem Zeichen, das keine Ziffer darstellt. Entspricht [^0-9]. | |
Entspricht einem Seitenumbruchzeichen. | |
Entspricht einem Zeilenumbruchzeichen. | |
Entspricht einem Wagenrücklaufzeichen. | |
Entspricht allen Leerzeichen, einschließlich Leerzeichen, Tabulatoren, Seitenumbrüchen usw. Entspricht „[ \f\n\r\t\v]“. | |
Entspricht jedem nicht-leeren Leerzeichen. Entspricht „[^ \f\n\r\t\v]“. | |
Entspricht einem Tabulatorzeichen. | |
Entspricht einem vertikalen Tabulatorzeichen. | |
Entspricht jedem Zeichen, das ein Wort darstellt und einen Unterstrich enthält. Entspricht „[A-Za-z0-9_]“. | |
Entspricht jedem Zeichen, das kein Wort darstellt. Entspricht „[^A-Za-z0-9_]“. | |
| Entspricht num, wobei num eine positive ganze Zahl ist. Bezieht sich auf gespeicherte Zuordnungen. Beispielsweise entspricht „(.)\1“ zwei aufeinanderfolgenden identischen Zeichen. |
| Entspricht n, wobei n ein oktaler Escape-Wert ist. Oktale Escape-Werte müssen aus 1, 2 oder 3 Ziffern bestehen. Beispielsweise entsprechen sowohl „\11“ als auch „\011“ einem Tabulatorzeichen. „\0011“ entspricht „\001“ & „1“. Oktale Escape-Werte dürfen den Wert 256 nicht überschreiten. Sollte dies der Fall sein, werden nur die ersten beiden Ziffern im Ausdruck berücksichtigt. Ermöglicht die Verwendung der Codes ASCII in regulären Ausdrücken. |
| Entspricht n, wobei n ein hexadezimaler Escape-Wert ist. Hexadezimale Escape-Werte müssen zwingend aus zwei Ziffern bestehen. Beispielsweise entspricht „\x41“ dem Zeichen „A“. „\x041“ entspricht „\x04“ und „1“. Ermöglicht die Verwendung der Codes ASCII in regulären Ausdrücken. |
Ein Element in einer Vorlage kann ein- oder mehrfach vorkommen. Betrachten wir einige Beispiele rund um das Symbol \d, das für eine Ziffer steht:
Vorlage | Bedeutung |
eine Ziffer | |
0 oder 1 Ziffer | |
0 oder mehr Ziffern | |
1 oder mehr Ziffern | |
2 Ziffern | |
mindestens 3 Ziffern | |
zwischen 5 und 7 Ziffern |
Stellen wir uns nun das Modell vor, das das erwartete Format für eine Zeichenkette beschreiben kann:
gesuchte Zeichenfolge | Modell |
\d{2}/\d{2}/\d{2} | |
\d{2}:\d{2}:\d{2} | |
\d+ | |
\s* | |
\s*\d+\s* | |
\s*[+|-]?\s*\d+\s* | |
\s*\d+(.\d*)?\s* | |
\s*[+|]?\s*\d+(.\d*)?\s* | |
\bjuste\b | |
Man kann angeben, an welcher Stelle in der Zeichenfolge nach dem Muster gesucht werden soll:
Muster | Bedeutung |
Die Vorlage steht am Anfang der Zeichenfolge | |
Die Vorlage beendet die Zeichenfolge | |
Die Vorlage beginnt und beendet die Zeichenfolge | |
Das Muster wird im gesamten String gesucht, beginnend am Anfang des Strings. |
Gesuchte Zeichenfolge | Muster |
!$ | |
\.$ | |
^// | |
^\s*\w+\s*$ | |
^\s*\w+\s*\w+\s*$ | |
\bsecret\b |
Teilmengen eines Musters können „extrahiert“ werden. So lässt sich nicht nur überprüfen, ob eine Zeichenfolge einem bestimmten Muster entspricht, sondern es können auch die Elemente aus dieser Zeichenfolge extrahiert werden, die den in Klammern gesetzten Teilmengen des Musters entsprechen. Wenn man also eine Zeichenfolge analysiert, die ein Datum im Format TT/MM/JJ enthält, und zusätzlich die Elemente TT, MM und JJ dieses Datums extrahieren möchte, verwendet man das Muster (\d\d)/(\d\d)/(\d\d).
4.9.1. Überprüfen, ob eine Zeichenkette einem bestimmten Muster entspricht
Ein Objekt vom Typ „Regex“ wird wie folgt erstellt:
Der Konstruktor erstellt ein „Regulärer Ausdruck“-Objekt anhand eines als Parameter übergebenen Musters (pattern). Sobald der reguläre Ausdruck erstellt ist, kann er mit der Methode IsMatch mit Zeichenfolgen verglichen werden:
IsMatch gibt „wahr“ zurück, wenn die Eingabezeichenfolge mit dem Muster des regulären Ausdrucks übereinstimmt. Hier ein Beispiel:
' Optionen
Option Strict On
Option Explicit On
' Namensräume
Imports System
Imports System.Collections
Imports System.Text.RegularExpressions
Module regex1
Sub Main()
' ein regulärer Ausdruck als Vorlage
Dim modèle1 As String = "^\s*\d+\s*$"
Dim regex1 As New Regex(modèle1)
' Ein Exemplar mit dem Muster vergleichen
Dim exemplaire1 As String = " 123 "
If regex1.IsMatch(exemplaire1) Then
affiche(("[" + exemplaire1 + "] correspond au modèle [" + modèle1 + "]"))
Else
affiche(("[" + exemplaire1 + "] ne correspond pas au modèle [" + modèle1 + "]"))
End If
Dim exemplaire2 As String = " 123a "
If regex1.IsMatch(exemplaire2) Then
affiche(("[" + exemplaire2 + "] correspond au modèle [" + modèle1 + "]"))
Else
affiche(("[" + exemplaire2 + "] ne correspond pas au modèle [" + modèle1 + "]"))
End If
End Sub
' Anzeigen
Sub affiche(ByVal msg As String)
Console.Out.WriteLine(msg)
End Sub
End Module
und die Ausführungsergebnisse:
dos>vbc /r:system.dll regex1.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4 pour Microsoft (R) .NET Framework version 1.1.4322.573
dos>regex1
[ 123 ] correspond au modèle [^\s*\d+\s*$]
[ 123a ] ne correspond pas au modèle [^\s*\d+\s*$]
4.9.2. Alle Elemente einer Zeichenkette finden, die einem Muster entsprechen
Die Methode „Matches“
gibt eine Sammlung von Elementen der Zeichenfolge input zurück, die dem Muster entsprechen, wie das folgende Beispiel zeigt:
' Optionen
Option Strict On
Option Explicit On
' Namensräume
Imports System
Imports System.Collections
Imports System.Text.RegularExpressions
Module regex2
Sub Main()
' mehrere Vorkommen des Musters im Exemplar
Dim modèle2 As String = "\d+"
Dim regex2 As New Regex(modèle2) '
Dim exemplaire3 As String = " 123 456 789 "
Dim résultats As MatchCollection = regex2.Matches(exemplaire3)
affiche(("Modèle=[" + modèle2 + "],exemplaire=[" + exemplaire3 + "]"))
affiche(("Il y a " & résultats.Count & " occurrences du modèle dans l'exemplaire "))
Dim i As Integer
For i = 0 To résultats.Count - 1
affiche((résultats(i).Value & " en position " & résultats(i).Index))
Next i
End Sub
'anzeigen
Sub affiche(ByVal msg As String)
Console.Out.WriteLine(msg)
End Sub
End Module
Die Klasse MatchCollection verfügt über die Eigenschaft „Count“, die die Anzahl der Elemente in der Sammlung angibt. Wenn résultats ein Objekt vom Typ MatchCollection ist, dann ist résultats(i) das i-te Element dieser Sammlung und vom Typ „Match“. In unserem Beispiel ist résultats die Menge der Elemente der Zeichenkette exemplaire3, die dem Muster modèle2 entsprechen, und résultats(i) ist eines dieser Elemente. Die Klasse Match verfügt über zwei Eigenschaften, die uns hier interessieren:
- Value: der Wert des Match-Objekts, also das Element, das dem Modell entspricht
- Index: die Position, an der das Element in der durchsuchten Zeichenkette gefunden wurde
Die Ergebnisse der Ausführung des vorherigen Programms:
dos>vbc /r:system.dll regex2.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4p our Microsoft (R) .NET Framework version 1.1.4322.573
dos>regex2
Modèle=[\d+],exemplaire=[ 123 456 789 ]
Il y a 3 occurrences du modèle dans l'exemplaire
123 en position 2
456 en position 7
789 en position 12
4.9.3. Teile eines Musters extrahieren
Teilmengen eines Musters können „extrahiert“ werden. So lässt sich nicht nur überprüfen, ob eine Zeichenfolge einem bestimmten Muster entspricht, sondern es können auch die Elemente aus dieser Zeichenfolge extrahiert werden, die den in Klammern gesetzten Teilmengen des Musters entsprechen. Wenn man also eine Zeichenfolge analysiert, die ein Datum im Format TT/MM/JJ enthält, und zusätzlich die Elemente TT, MM und JJ dieses Datums extrahieren möchte, verwendet man das Muster (\d\d)/(\d\d)/(\d\d). Betrachten wir das folgende Beispiel:
' Optionen
Option Strict On
Option Explicit On
' Namensräume
Imports System
Imports System.Collections
Imports System.Text.RegularExpressions
Module regex2
Sub Main()
' Erfassung von Elementen in der Vorlage
Dim modèle3 As String = "(\d\d):(\d\d):(\d\d)"
Dim regex3 As New Regex(modèle3)
Dim exemplaire4 As String = "Il est 18:05:49"
' Vorlagenprüfung
Dim résultat As Match = regex3.Match(exemplaire4)
If résultat.Success Then
' Die Instanz entspricht der Vorlage
affiche(("L'exemplaire [" + exemplaire4 + "] correspond au modèle [" + modèle3 + "]"))
' Gruppen werden angezeigt
Dim i As Integer
For i = 0 To résultat.Groups.Count - 1
affiche(("groupes[" & i & "]=[" & résultat.Groups(i).Value & "] en position " & résultat.Groups(i).Index))
Next i
Else
' Das Exemplar entspricht nicht der Vorlage
affiche(("L'exemplaire[" + exemplaire4 + " ne correspond pas au modèle [" + modèle3 + "]"))
End If
End Sub
'zeigt an
Sub affiche(ByVal msg As String)
Console.Out.WriteLine(msg)
End Sub
End Module
Die Ausführung dieses Programms liefert folgende Ergebnisse:
dos>vbc /r:system.dll regex3.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4
dos>regex3
L'exemplaire [Il est 18:05:49] correspond au modèle [(\d\d):(\d\d):(\d\d)]
groupes[0]=[18:05:49] en position 7
groupes[1]=[18] en position 7
groupes[2]=[05] en position 10
groupes[3]=[49] en position 13
Die Neuerung befindet sich im folgenden Codeabschnitt:
' Vorlagenprüfung
Dim résultat As Match = regex3.Match(exemplaire4)
If résultat.Success Then
' Das Exemplar entspricht der Vorlage
affiche(("L'exemplaire [" + exemplaire4 + "] correspond au modèle [" + modèle3 + "]"))
' Gruppen werden angezeigt
Dim i As Integer
For i = 0 To résultat.Groups.Count - 1
affiche(("groupes[" & i & "]=[" & résultat.Groups(i).Value & "] en position " & résultat.Groups(i).Index))
Next i
Else
Die Zeichenfolge exemplaire4 wird mithilfe der Methode Match mit dem Muster regex3 verglichen. Diese Methode gibt ein bereits vorgestelltes Objekt Match zurück. Wir verwenden hier zwei neue Eigenschaften dieser Klasse:
- Success: gibt an, ob eine Übereinstimmung vorliegt
- Groups: Sammlung, in der
- Groups[0] dem Teil der Zeichenkette entspricht, der dem Muster
- Groups[i] (i >= 1) der Klammergruppe Nr. i entspricht
Wenn das Ergebnis den Typ Match hat, dann ist résultats.Groups vom Typ GroupCollection und résultats.Groups[i] vom Typ Group. Die Klasse Group verfügt über zwei Eigenschaften, die wir hier verwenden:
- Value: Der Wert des Group-Objekts, dessen Element dem Inhalt einer Klammer entspricht
- Index: Die Position, an der das Element in der durchsuchten Zeichenkette gefunden wurde
4.9.4. Ein Übungsprogramm
Es ist manchmal eine echte Herausforderung, den regulären Ausdruck zu finden, mit dem wir überprüfen können, ob eine Zeichenkette tatsächlich einem bestimmten Muster entspricht. Mit dem folgenden Programm können Sie üben. Es fragt nach einem Muster und einer Zeichenkette und gibt dann an, ob die Zeichenkette dem Muster entspricht oder nicht.
' Optionen
Option Strict On
Option Explicit On
' Namensräume
Imports System
Imports System.Collections
Imports System.Text.RegularExpressions
Imports Microsoft.visualbasic
Module regex4
Sub Main()
' ein regulärer Ausdruck als Vorlage
Dim modèle, chaine As String
Dim regex As Regex = Nothing
Dim résultats As MatchCollection
' Der Benutzer wird aufgefordert, die Vorlagen und Instanzen anzugeben, die mit dieser verglichen werden sollen
Dim terminé1 As Boolean = False
Do While Not terminé1
Dim erreur As Boolean = True
Do While Not terminé1 And erreur
' Das Muster wird abgefragt
Console.Out.Write("Tapez le modèle à tester ou fin pour arrêter :")
modèle = Console.In.ReadLine()
' Fertig?
If modèle.Trim().ToLower() = "fin" Then
terminé1 = True
Else
' Der reguläre Ausdruck wird erstellt
Try
regex = New Regex(modèle)
erreur = False
Catch ex As Exception
Console.Error.WriteLine(("Erreur : " + ex.Message))
End Try
End If
Loop
' Fertig?
If terminé1 Then Exit Sub
' Der Benutzer wird aufgefordert, die mit dem Muster zu vergleichenden Instanzen anzugeben
Dim terminé2 As Boolean = False
Do While Not terminé2
Console.Out.Write(("Tapez la chaîne à comparer au modèle [" + modèle + "] ou fin pour arrêter :"))
chaine = Console.In.ReadLine()
' fertig?
If chaine.Trim().ToLower() = "fin" Then
terminé2 = True
Else
' Der Vergleich wird durchgeführt
résultats = regex.Matches(chaine)
' Erfolgreich?
If résultats.Count = 0 Then
Console.Out.WriteLine("Je n'ai pas trouvé de correspondances")
Else
' Die mit der Vorlage übereinstimmenden Elemente werden angezeigt
Dim i As Integer
For i = 0 To résultats.Count - 1
Console.Out.WriteLine(("J'ai trouvé la correspondance [" & résultats(i).Value & "] en position " & résultats(i).Index))
' Unterelemente
If résultats(i).Groups.Count <> 1 Then
Dim j As Integer
For j = 1 To (résultats(i).Groups.Count) - 1
Console.Out.WriteLine((ControlChars.Tab & "sous-élément [" & résultats(i).Groups(j).Value & "] en position " & résultats(i).Groups(j).Index))
Next j
End If
Next i
End If
End If
Loop
Loop
End Sub
'zeigt an
Sub affiche(ByVal msg As String)
Console.Out.WriteLine(msg)
End Sub
End Module
Hier ein Ausführungsbeispiel:
Tapez le modèle à tester ou fin pour arrêter :\d+
Tapez la chaîne à comparer au modèle [\d+] ou fin pour arrêter :123 456 789
J'ai trouvé la correspondance [123] en position 0
J'ai trouvé la correspondance [456] en position 4
J'ai trouvé la correspondance [789] en position 8
Tapez la chaîne à comparer au modèle [\d+] ou fin pour arrêter :fin
Tapez le modèle à tester ou fin pour arrêter :(\d\d):(\d\d)
Tapez la chaîne à comparer au modèle [(\d\d):(\d\d)] ou fin pour arrêter :14:15 abcd 17:18 xyzt
J'ai trouvé la correspondance [14:15] en position 0
sous-élément [14] en position 0
sous-élément [15] en position 3
J'ai trouvé la correspondance [17:18] en position 11
sous-élément [17] en position 11
sous-élément [18] en position 14
Tapez la chaîne à comparer au modèle [(\d\d):(\d\d)] ou fin pour arrêter :fin
Tapez le modèle à tester ou fin pour arrêter :^\s*\d+\s*$
Tapez la chaîne à comparer au modèle [^\s*\d+\s*$] ou fin pour arrêter : 1456
J'ai trouvé la correspondance [ 1456] en position 0
Tapez la chaîne à comparer au modèle [^\s*\d+\s*$] ou fin pour arrêter :fin
Tapez le modèle à tester ou fin pour arrêter :^\s*(\d+)\s*$
Tapez la chaîne à comparer au modèle [^\s*(\d+)\s*$] ou fin pour arrêter :1456
J'ai trouvé la correspondance [1456] en position 0
sous-élément [1456] en position 0
Tapez la chaîne à comparer au modèle [^\s*(\d+)\s*$] ou fin pour arrêter :abcd 1
456
Je n'ai pas trouvé de correspondances
Tapez la chaîne à comparer au modèle [^\s*(\d+)\s*$] ou fin pour arrêter :fin
Tapez le modèle à tester ou fin pour arrêter :fin
4.9.5. Die Methode „Split“
Diese Methode haben wir bereits in der Klasse String kennengelernt:
Die Zeichenkette wird als eine Folge von Feldern betrachtet, die durch die im Array [separator] enthaltenen Zeichen getrennt sind. Das Ergebnis ist das Array dieser Felder.
Das Feldtrennzeichen der Zeichenkette ist hier eines der Zeichen aus dem Array separator. Mit der Methode Split der Klasse Regex können wir das Trennzeichen anhand eines Musters ausdrücken:
Die Zeichenfolge [input] wird in Felder zerlegt, wobei diese durch ein Trennzeichen getrennt werden, das dem Muster des aktuellen Objekts Regex entspricht. Nehmen wir beispielsweise an, wir hätten in einer Textdatei Zeilen der Form Feld1, Feld2, …, Feldn. Die Felder sind durch ein Komma getrennt, dem jedoch vor oder nach dem Komma Leerzeichen folgen können. Die Methode Split der Klasse string ist in diesem Fall nicht geeignet. Die Methode RegEx bietet die Lösung. Wenn „Zeile“ die gelesene Zeile ist, können die Felder wie folgt abgerufen werden:
abgerufen werden, wie das folgende Beispiel zeigt:
' Optionen
Option Strict On
Option Explicit On
' Namensräume
Imports System
Imports System.Text.RegularExpressions
Module regex5
Sub Main()
' eine Zeile
Dim ligne As String = "abc , def , ghi"
' eine Vorlage
Dim modèle As New Regex("\s*,\s*")
' Aufschlüsselung einer Zeile in Felder
Dim champs As String() = modèle.Split(ligne)
' Anzeige
Dim i As Integer
For i = 0 To champs.Length - 1
Console.Out.WriteLine(("champs[" & i & "]=[" & champs(i) & "]"))
Next i
End Sub
End Module
Die Ausführungsergebnisse:
dos>vbc /r:system.dll regex5.vb
Compilateur Microsoft (R) Visual Basic .NET version 7.10.3052.4
dos>regex5
champs[0]=[abc]
champs[1]=[def]
champs[2]=[ghi]
4.10. Die Klassen BinaryReader und BinaryWriter
Die Klassen BinaryReader und BinaryWriter dienen zum Lesen und Schreiben von Binärdateien. Betrachten wir die folgende Anwendung. Wir möchten ein Programm schreiben, das wie folgt aufgerufen wird:
// Syntax pg Text bin
// Eine Textdatei (Text) wird gelesen und ihr Inhalt in einem
// binäre Datei
// Die Textdatei enthält Zeilen der Form „Name: Alter“
//, die in einer Struktur vom Typ „string, int“ gespeichert werden sollen
Die Textdatei hat folgenden Inhalt:
Das Programm lautet wie folgt:
' Optionen
Option Strict On
Option Explicit On
' Namensräume
Imports System
Imports System.Text.RegularExpressions
Imports System.IO
' BinaryWriter()
Module bw1
' Syntax pg Text bin
' Eine Textdatei (Text) wird gelesen und ihr Inhalt in einem
' binäre Datei
' Die Textdatei enthält Zeilen der Form „Name: Alter“
' die in eine Struktur vom Typ „string, int“ gespeichert werden
Sub Main(ByVal arguments() As String)
' Es sind 2 Argumente erforderlich
Dim nbArgs As Integer = arguments.Length
If nbArgs <> 2 Then
Console.Error.WriteLine("syntaxe : pg texte binaire")
Environment.Exit(1)
End If
' Öffnen der Textdatei zum Lesen
Dim input As StreamReader = Nothing
Try
input = New StreamReader(arguments(0))
Catch ex As Exception
Console.Error.WriteLine("Erreur d'ouverture du fichier " & arguments(0) & "(" & ex.Message & ")")
Environment.Exit(2)
End Try
' Öffnen der Binärdatei zum Schreiben
Dim output As BinaryWriter = Nothing
Try
output = New BinaryWriter(New FileStream(arguments(1), FileMode.Create, FileAccess.Write))
Catch ex As Exception
Console.Error.WriteLine("Erreur d'ouverture du fichier " & arguments(1) & "(" & ex.Message & ")")
Environment.Exit(3)
End Try
' Textdatei lesen – Binärdatei schreiben
' Zeile der Textdatei
Dim ligne As String
' Feldtrennzeichen der Zeile
Dim séparateur As New Regex("\s*:\s*")
' Altersmuster
Dim modAge As New Regex("\s*\d+\s*")
Dim numLigne As Integer = 0
Dim traitementFini As Boolean
Dim champs As String()
ligne = input.ReadLine()
While Not (ligne Is Nothing)
traitementFini = False
' Leere Zeile?
If ligne.Trim() = "" Then
traitementFini = True
End If
' eine weitere Zeile
If Not traitementFini Then
numLigne += 1
' eine Zeile mit dem Namen: Alter
champs = séparateur.Split(ligne)
' Wir benötigen 2 Felder
If champs.Length <> 2 Then
Console.Error.WriteLine(("La ligne n° " & numLigne & " du fichier " & arguments(0) & " a un nombre de champs incorrect"))
' nächste Zeile
traitementFini = True
End If
End If
If Not traitementFini Then
' Das zweite Feld muss eine ganze Zahl >= 0 sein
If Not modAge.IsMatch(champs(1)) Then
Console.Error.WriteLine(("La ligne n° " & numLigne & " du fichier " & arguments(0) & " a un âge incorrect"))
' nächste Zeile
traitementFini = True
End If
' Die Daten werden in die Binärdatei geschrieben
output.Write(champs(0))
output.Write(Integer.Parse(champs(1)))
End If
'nächste Zeile
ligne = input.ReadLine()
End While
' Schließen der Dateien
input.Close()
output.Close()
End Sub
End Module
Werfen wir einen Blick auf die Vorgänge bezüglich der Klasse BinaryWriter:
- Das Objekt BinaryWriter wird durch den Vorgang
output = New BinaryWriter(New FileStream(arguments(1), FileMode.Create, FileAccess.Write))
Das Argument des Konstruktors muss ein Stream sein. Hier handelt es sich um einen Stream, der aus einer Datei (FileStream) erstellt wird, für die folgende Angaben gemacht werden:
- (Fortsetzung)
- den Namen
- die auszuführende Operation, hier FileMode.Create zum Erstellen der Datei
- die Zugriffsart, hier FileAccess.Write für einen Schreibzugriff auf die Datei
- den Schreibvorgang
' Die Daten werden in die Binärdatei geschrieben
output.Write(champs(0))
output.Write(Integer.Parse(champs(1)))
Die Klasse BinaryWriter verfügt über verschiedene überladene Methoden Write zum Schreiben der verschiedenen einfachen Datentypen
- den Vorgang zum Schließen des Datenstroms
Die Ergebnisse der vorherigen Ausführung werden uns vom folgenden Programm ausgegeben. Dieses akzeptiert ebenfalls zwei Argumente:
' Syntax: pg bin text
' eine Binärdatei „bin“ wird gelesen und ihr Inhalt in eine Textdatei („text“) gespeichert
' Die Binärdatei hat eine Struktur aus Zeichenketten und Ganzzahlen
' Die Textdatei enthält Zeilen der Form „Name: Alter“
Wir führen also den umgekehrten Vorgang durch. Wir lesen eine Binärdatei ein, um eine Textdatei zu erstellen. Wenn die erzeugte Textdatei mit der Originaldatei identisch ist, wissen wir, dass die Konvertierung von Text → Binär → Text erfolgreich verlaufen ist. Der Code lautet wie folgt:
' Optionen
Option Strict On
Option Explicit On
' Namensräume
Imports System
Imports System.Text.RegularExpressions
Imports System.IO
Module br1
' Syntax pg bin text
' Eine Binärdatei „bin“ wird gelesen und ihr Inhalt in eine Textdatei („text“) geschrieben
' Die Binärdatei hat die Struktur „string, int“
' Die Textdatei enthält Zeilen der Form „Name: Alter“
Sub Main(ByVal arguments() As String)
' Es sind 2 Argumente erforderlich
Dim nbArgs As Integer = arguments.Length
If nbArgs <> 2 Then
Console.Error.WriteLine("syntaxe : pg binaire texte")
Environment.Exit(1)
End If
' Öffnen der Binärdatei zum Lesen
Dim dataIn As BinaryReader = Nothing
Try
dataIn = New BinaryReader(New FileStream(arguments(0), FileMode.Open, FileAccess.Read))
Catch ex As Exception
Console.Error.WriteLine("Erreur d'ouverture du fichier " & arguments(0) & "(" & ex.Message & ")")
Environment.Exit(2)
End Try
' Öffnen der Textdatei zum Schreiben
Dim dataOut As StreamWriter = Nothing
Try
dataOut = New StreamWriter(arguments(1))
dataOut.AutoFlush = True
Catch ex As Exception
Console.Error.WriteLine("Erreur d'ouverture du fichier " & arguments(1) & "(" & ex.Message & ")")
Environment.Exit(3)
End Try
' Binärdatei lesen – Textdatei schreiben
Dim nom As String ' nom d'une personne
Dim age As Integer ' son âge
' Verarbeitungsschleife für die Binärdatei
While True
' Name lesen
Try
nom = dataIn.ReadString()
Catch
' Ende der Datei
Exit Sub
End Try
' Alter lesen
Try
age = dataIn.ReadInt32()
Catch
Console.Error.WriteLine("Le fichier " & arguments(0) + " ne semble pas avoir un format correct")
Exit Sub
End Try
' Schreiben in Textdatei
dataOut.WriteLine(nom & ":" & age)
System.Console.WriteLine(nom & ":" & age)
End While
' alles schließen
dataIn.Close()
dataOut.Close()
End Sub
End Module
Werfen wir einen Blick auf die Vorgänge rund um die Klasse BinaryReader:
- Das Objekt BinaryReader wird durch den Vorgang
dataIn = New BinaryReader(New FileStream(arguments(0), FileMode.Open, FileAccess.Read))
Das Argument des Konstruktors muss ein Stream sein. Hier handelt es sich um einen Stream, der aus einer Datei (FileStream) erstellt wurde, für die wir Folgendes angeben:
- (Fortsetzung)
- den Namen
- die auszuführende Operation, hier FileMode.Open zum Öffnen einer vorhandenen Datei
- die Zugriffsart, hier FileAccess.Read für den Lesezugriff auf die Datei
- den Lesevorgang
Die Klasse BinaryReader verfügt über verschiedene Methoden ReadXX zum Lesen der verschiedenen einfachen Datentypen
- der Vorgang zum Schließen des Datenstroms
Wenn man die beiden Programme nacheinander ausführt und dabei personnes.txt in personnes.bin und anschließend personnes.bin in personnes.txt2 umwandelt, erhält man:

