Skip to content

4. Veelgebruikte klassen van .NET

Hier presenteren we enkele interessante klassen van het .NET-platform, die zelfs voor een beginner interessant zijn. We laten eerst zien hoe je informatie kunt vinden over de honderden beschikbare klassen.

4.1. Hulp zoeken met SDK.NET

4.1.1. wincv

Als je alleen SDK hebt geïnstalleerd en niet Visual Studio.NET, kun je het programma wincv.exe gebruiken, dat zich normaal gesproken in de SDK-structuur bevindt, bijvoorbeeld C:\Program Files\Microsoft Visual Studio.NET 2003\SDK\v1.1. Wanneer u dit hulpprogramma start, krijgt u de volgende interface te zien:

Typ in (1) de naam van de gewenste klasse in. Dit geeft in (2) verschillende mogelijke thema’s weer. Kies het juiste thema en je krijgt het resultaat in (3), in dit geval de klasse HashTable. Deze methode is geschikt als je de naam van de gezochte klasse kent. Als je de lijst met mogelijkheden van het .NET of het bestand HTML StartHere.htm, dat zich eveneens direct in de installatiemap van SSK.Net bevindt, bijvoorbeeld C:\Program Files\Microsoft Visual Studio .NET 2003\SDK\v1.

Image

De link .NET Framework SDK Documentatie is de link die u moet volgen om een overzicht te krijgen van de klassen .NET:

Image

Daar volgen we de link [Bibliothèque de classes]. Daar vindt u de lijst met alle klassen van .NET:

Image

Laten we bijvoorbeeld de link System.Collections volgen. Deze naamruimte bevat diverse klassen die collecties implementeren, waaronder de klasse HashTable:

Image

Laten we de onderstaande link HashTable volgen:

Image

We krijgen de volgende pagina te zien:

Image

Let hieronder op de positie van de hand. Deze wijst naar een link waarmee de gewenste programmeertaal kan worden geselecteerd, in dit geval Visual Basic.

Daar vindt u het prototype van de klasse en enkele voorbeelden van het gebruik ervan. Volg de onderstaande link [Hashtable, membres]:

Image

We krijgen de volledige beschrijving van de klasse te zien:

Image

Deze methode is de beste manier om SDK en de bijbehorende klassen te verkennen. De tool WinCV is handig wanneer je de klasse al enigszins kent, maar sommige van de leden ervan bent vergeten. Met WinCV kun je dan snel de klasse en de bijbehorende leden terugvinden.

4.2. Hulp zoeken bij klassen met VS.NET

Hier geven we enkele tips om hulp te vinden met Visual Studio.NET

4.2.1. Optie Help

Kies de optie [?] in het menu.

Image

Het volgende venster verschijnt:

Image

In de vervolgkeuzelijst kun je een helpfilter kiezen. Hier kiezen we het filter [Visual Basic].

Image

Er zijn twee handige helpfuncties:

  • de helpfunctie over de taal VB.NET zelf (syntaxis)
  • de help over de classes.NET die door de taal VB.NET kunnen worden gebruikt

De helpfunctie voor de taal VB.NET is toegankelijk via [Visual Studio.NET/Visual Basic et Visual C#/Reference/Visual Basic]:

Image

U krijgt dan de volgende help-pagina te zien:

Image

Van daaruit bieden de verschillende subrubrieken hulp bij diverse onderwerpen van VB.NET. Let vooral op de tutorials van VB.NET:

Image

Om toegang te krijgen tot de verschillende klassen van het platform .NET, kiezen we de helpfunctie [Visual Studio.NET/.NET Framework].

Image

We zullen met name kijken naar de rubriek [Référence/Bibliothèque de classes]:

Image

Stel dat we geïnteresseerd zijn in de klasse [ArrayList]. Deze bevindt zich in de naamruimte [System.Collections]. Dit is belangrijk om te weten, anders geven we de voorkeur aan de hieronder beschreven zoekmethode. We krijgen de volgende helptekst:

Image

De link [ArrayList, classe] geeft een overzicht van de klasse:

Image

Dit soort pagina bestaat voor alle klassen. Het geeft een samenvatting van de klasse met voorbeelden. Voor een beschrijving van de leden van de klasse volgt men de link [ArrayList, membres]:

Image

4.2.2. Help/Index

Image

Met de optie [Aide/index] kunt u gerichter hulp zoeken dan met de vorige hulpoptie. U hoeft alleen maar het gezochte trefwoord in te voeren:

Image

Het voordeel van deze methode ten opzichte van de vorige is dat je niet hoeft te weten waar in het helpsysteem je het gezochte onderwerp kunt vinden. Dit is waarschijnlijk de beste methode voor een gerichte zoekopdracht, terwijl de andere methode geschikter is om te ontdekken wat de helpfunctie allemaal te bieden heeft.

4.3. De klasse String

De klasse String beschikt over talrijke eigenschappen en methoden. Hier volgen er enkele:

Public ReadOnly Property Length As Integer
aantal tekens in de tekenreeks
Public Default ReadOnly Property 
Chars(ByVal index As Integer) As Char
standaard geïndexeerde eigenschap. [String].Chars(i) is het teken met nummer i in de tekenreeks
Public Function EndsWith(ByVal value As String) 
As Boolean
geeft ‘waar’ terug als de tekenreeks eindigt op waarde
Public Function StartsWith(ByVal value As String) 
As Boolean
is waar als de tekenreeks begint met de waarde
Overloads Public Function Equals(ByVal value 
As String) As Boolean
geeft 'waar' terug als de tekenreeks gelijk is aan 'value'
Overloads Public Function IndexOf(ByVal value 
As String) As Integer
geeft de eerste positie in de tekenreeks 'value' weer – het zoeken begint bij teken nr. 0
Overloads Public Function IndexOf(ByVal value 
As String,ByVal startIndex As Integer) As Integer
geeft de eerste positie in de tekenreeks 'value' weer – de zoekopdracht begint bij teken nr. startIndex
Overloads Public Shared Function 
Join(ByVal separator As String,ByVal value() 
As String) As String
klassemethode - retourneert een tekenreeks die het resultaat is van het samenvoegen van de waarden uit de array value met het scheidingsteken separator
Overloads Public Function Replace(ByVal oldChar 
As Char,ByVal newChar As Char) As String
geeft een kopie van de huidige tekenreeks terug, waarbij het teken oldChar is vervangen door het teken newChar
Overloads Public Function Split(ByVal ParamArray
separator() As Char) As String()
de tekenreeks wordt gezien als een reeks velden, gescheiden door de tekens in de array separator. Het resultaat is de array van deze velden
Overloads Public Function Substring(
ByVal startIndex As Integer,ByVal length As Integer) 
As String
substring van de huidige tekenreeks die begint op positie startIndex en length tekens lang is
Overloads Public Function ToLower() 
As String
zet de huidige tekenreeks in kleine letters
Overloads Public Function ToUpper() 
As String
zet de huidige tekenreeks in hoofdletters
Overloads Public Function Trim() 
As String
verwijdert de spaties aan het begin en einde van de huidige tekenreeks

Een tekenreeks C kan worden beschouwd als een array van tekens. Dus

  • is C.Chars(i) het i-de teken van C
  • C.Length is het aantal tekens van C

Laten we het volgende voorbeeld eens bekijken:


' opties
Option Strict On
Option Explicit On 

' naamruimten
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

    ' weergeeft
    Sub affiche(ByVal msg As [String])
        ' toont bericht
        Console.Out.WriteLine(msg)
    End Sub
End Module

De uitvoering levert de volgende resultaten op:

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]

Laten we eens een nieuw voorbeeld bekijken:


' opties
Option Strict On
Option Explicit On 

' naamruimten
Imports System

Module string2
    Sub Main()
        ' de te analyseren regel
        Dim ligne As String = "un:deux::trois:"
        ' de veldscheidingstekens
        Dim séparateurs() As Char = {":"c}
        ' splitsen
        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
        ' samenvoegen
        Console.Out.WriteLine(("join=[" + System.String.Join(":", champs) + "]"))
    End Sub
End Module

en de uitvoerresultaten:

Champs[0]=un
Champs[1]=deux
Champs[2]=
Champs[3]=trois
Champs[4]=
join=[un:deux::trois:]

Met de methode Split van de klasse String kunnen de velden van een tekenreeks in een array worden geplaatst. De definitie van de hier gebruikte methode is als volgt:

Overloads Public Function Split(ByVal ParamArray separator() As Char) As String()
separator
tekenreeks. Deze tekens vertegenwoordigen de tekens die worden gebruikt om de velden in de tekenreeks van elkaar te scheiden. Als de tekenreeks bijvoorbeeld [champ1, champ2, champ3] is, kan separator=new char() {","c} worden gebruikt. Als het scheidingsteken een reeks spaties is, wordt separator=nothing gebruikt.
résultat
array van tekenreeksen waarbij elk element een veld van de tekenreeks is.

De methode Join is een statische methode van de klasse String:

Overloads Public Shared Function Join(ByVal separator As String,ByVal value() As String) As String
value
array van tekenreeksen
separator
een tekenreeks die als veldscheidingsteken zal dienen
résultat
een tekenreeks die is gevormd door de elementen van de array value aan elkaar te plakken, gescheiden door de tekenreeks separator.

4.4. De klasse Array

De klasse Array implementeert een array. In ons voorbeeld gebruiken we de volgende eigenschappen en methoden:

Public ReadOnly Property Length As Integer
eigenschap – aantal elementen in de array
Overloads Public Shared Function BinarySearch
(ByVal array As Array,ByVal index As Integer,
ByVal length As Integer,ByVal value As Object) As Integer
klassemethode - geeft de positie van value in de gesorteerde array array weer - zoekt vanaf de positie index en met length elementen
Overloads Public Shared Sub Copy(ByVal sourceArray 
As Array,ByVal destinationArray As Array,
ByVal length As Integer)
klassemethode - kopieert elementen van length uit sourceArray naar destinationArray - destinationArray wordt hiervoor aangemaakt
Overloads Public Shared Sub Sort(ByVal array As Array)
klassenmethode - sorteert de array array - deze moet een gegevenstype bevatten met een standaard sorteerfunctie (tekenreeksen, getallen).

Het volgende programma illustreert het gebruik van de klasse Array:


' opties
Option Strict On
Option Explicit On 

' naamruimten
Imports System

Module test
    Sub Main()
        ' het uitlezen van de elementen van een array die via het toetsenbord zijn ingevoerd
        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é
            ' vraag
            Console.Out.Write(("Elément (réel) " & i & " du tableau (rien pour terminer) : "))
            ' het antwoord uitlezen
            réponse = Console.ReadLine().Trim()
            ' einde van de invoer als de tekenreeks leeg is
            If réponse.Equals("") Then
                Exit While
            End If
            ' controle van de invoer
            Try
                élément = [Double].Parse(réponse)
                erreur = False
            Catch
                Console.Error.WriteLine("Saisie incorrecte, recommencez")
                erreur = True
            End Try
            ' als er geen fout is
            If Not erreur Then
                ' nieuwe tabel om het nieuwe element op te nemen
                éléments2 = New Double(i) {}
                ' kopieer oude array naar nieuwe array
                If i <> 0 Then
                    Array.Copy(éléments1, éléments2, i)
                End If
                ' de nieuwe tabel wordt de oude tabel
                éléments1 = éléments2
                ' de nieuwe tabel is niet meer nodig
                éléments2 = Nothing
                ' nieuw element invoegen
                éléments1(i) = élément
                ' er is een element bijgekomen in de tabel
                i += 1
            End If
        End While
        ' weergave van de ongesorteerde tabel
        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
        ' de tabel sorteren
        System.Array.Sort(éléments1)
        ' Weergave van de gesorteerde tabel
        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
        ' Zoeken
        While Not terminé
            ' vraag
            Console.Out.Write("Elément cherché (rien pour arrêter) : ")
            ' antwoord lezen en controleren
            réponse = Console.ReadLine().Trim()
            ' klaar?
            If réponse.Equals("") Then
                Exit While
            End If
            ' controle
            Try
                élément = [Double].Parse(réponse)
                erreur = False
            Catch
                Console.Error.WriteLine("Saisie incorrecte, recommencez")
                erreur = True
            End Try
            ' als er geen fout is
            If Not erreur Then
                ' zoeken we het element in de gesorteerde array
                i = System.Array.BinarySearch(éléments1, 0, éléments1.Length, élément)
                ' Weergave van het antwoord
                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

De schermresultaten zijn als volgt:

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) :

Het eerste deel van het programma maakt een array aan op basis van numerieke gegevens die via het toetsenbord worden ingevoerd. De grootte van de array kan niet vooraf worden bepaald, aangezien het aantal elementen dat de gebruiker zal invoeren onbekend is. Er wordt daarom gewerkt met twee arrays: éléments1 en éléments2.


                ' nieuwe array om het nieuwe element op te nemen
                éléments2 = New Double(i) {}
                ' de oude tabel naar de nieuwe tabel kopiëren
                If i <> 0 Then
                    Array.Copy(éléments1, éléments2, i)
                End If
                ' de nieuwe tabel wordt de oude tabel
                éléments1 = éléments2
                ' de nieuwe tabel is niet meer nodig
                éléments2 = Nothing
                ' nieuw element invoegen
                éléments1(i) = élément
                ' een extra element in de tabel
                i += 1

De array éléments1 bevat de momenteel ingevoerde waarden. Wanneer de gebruiker een nieuwe waarde toevoegt, wordt een array éléments2 aangemaakt met één element meer dan éléments1, de inhoud van éléments1 wordt gekopieerd naar éléments2 (Array.Copy), laten we éléments1 naar éléments2 ‘verwijzen’ en voegen we ten slotte het nieuwe element toe aan éléments1. Dit is een complex proces dat kan worden vereenvoudigd door in plaats van een array met vaste grootte (Array) een array met variabele grootte (ArrayList) te gebruiken.

De array wordt gesorteerd met de methode Array.Sort. Deze methode kan worden aangeroepen met verschillende parameters die de sorteerregels specificeren. Zonder parameters wordt hier standaard in oplopende volgorde gesorteerd. Ten slotte maakt de methode Array.BinarySearch het mogelijk om een element in een gesorteerde array te zoeken.

4.5. De klasse ArrayList

Met de klasse ArrayList kunnen arrays met variabele grootte tijdens de uitvoering van het programma worden geïmplementeerd, wat met de vorige klasse Array niet mogelijk is. Hieronder volgen enkele veelgebruikte eigenschappen en methoden:

Public Sub New()
maakt een lege lijst aan
Public Overridable ReadOnly Property Count 
As Integer  Implements ICollection.Count
aantal elementen in de verzameling
Public Overridable Function Add(ByVal value 
As Object) As Integer Implements IList.Add
voegt het object 'value' toe aan het einde van de verzameling
Public Overridable Sub Clear() 
Implements IList.Clear
wist de lijst
Overloads Public Overridable Function 
IndexOf(ByVal value As Object) As Integer 
Implements IList.IndexOf
index van het object 'value' in de lijst of -1 als het niet bestaat
Overloads Public Overridable Function 
IndexOf(ByVal value As Object, ByVal startIndex 
As Integer) As Integer
idem, maar zoekend vanaf element nr. startIndex
Overloads Public Overridable Function 
LastIndexOf(ByVal value As Object) As Integer
idem, maar geeft de index van de laatste keer dat 'value' in de lijst voorkomt
Overloads Public Overridable Function 
LastIndexOf(ByVal value As Object, ByVal startIndex As Integer) As Integer
idem, maar zoekend vanaf element nr. startIndex
Public Overridable Sub Remove( ByVal obj As Object)
Implements IList.Remove
verwijder het object obj als het in de lijst voorkomt
Public Overridable Sub RemoveAt(ByVal index As Integer) 
Implements IList.RemoveAt
verwijdert het element met index uit de lijst
Overloads Public Overridable Function 
BinarySearch(ByVal value As Object) As Integer
geeft de positie van het object 'value' in de lijst terug, of -1 als het er niet in voorkomt. De lijst moet gesorteerd zijn
Overloads Public Overridable Sub Sort()
sorteert de lijst. Deze moet objecten bevatten met een vooraf gedefinieerde volgorde (tekenreeksen, getallen)
Overloads Public Overridable Sub 
Sort(ByVal comparer As IComparer)
sorteert de lijst volgens de volgorde die door de functie ‘vergelijken’ is vastgesteld

Laten we het voorbeeld met objecten van het type Array nog eens bekijken en het nu toepassen op objecten van het type ArrayList:


' opties
Option Strict On
Option Explicit On 

' naamruimten
Imports System
Imports System.Collections

Module test
    Sub Main()
        ' elementen van een tabel lezen die via het toetsenbord zijn ingevoerd
        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é
            ' vraag
            Console.Out.Write(("Elément (réel) " & i & " du tableau (rien pour terminer) : "))
            ' het antwoord lezen
            réponse = Console.ReadLine().Trim()
            ' einde van de invoer als de tekenreeks leeg is
            If réponse.Equals("") Then
                Exit While
            End If
            ' controle van de invoer
            Try
                élément = Double.Parse(réponse)
                erreur = False
            Catch
                Console.Error.WriteLine("Saisie incorrecte, recommencez")
                erreur = True
            End Try
            ' als er geen fout is
            If Not erreur Then
                ' nog een element aan de tabel toevoegen
                éléments.Add(élément)
            End If
        End While
        ' weergave van ongesorteerde tabel
        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()
        ' weergave van gesorteerde tabel
        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
        ' Zoeken
        While Not terminé
            ' vraag
            Console.Out.Write("Elément cherché (rien pour arrêter) : ")
            ' antwoord lezen en controleren
            réponse = Console.ReadLine().Trim()
            ' klaar?
            If réponse.Equals("") Then
                Exit While
            End If
            ' controle
            Try
                élément = [Double].Parse(réponse)
                erreur = False
            Catch
                Console.Error.WriteLine("Saisie incorrecte, recommencez")
                erreur = True
            End Try
            ' als er geen fout is
            If Not erreur Then
                ' zoeken we het element in de gesorteerde array
                i = éléments.BinarySearch(élément)
                ' Weergave antwoord
                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

De uitvoerresultaten zijn als volgt:

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. De klasse Hashtable

Met de klasse Hashtable kan een woordenboek worden geïmplementeerd. Een woordenboek kan worden gezien als een tabel met twee kolommen:

De sleutels zijn uniek, c.a.d, wat betekent dat er geen twee identieke sleutels kunnen zijn. De belangrijkste methoden en eigenschappen van de klasse Hashtable zijn de volgende:

Public Sub New()
maakt een leeg woordenboek aan
Public Overridable Sub Add(ByVal key As
Object,ByVal value As Object) 
Implements IDictionary.Add
voegt een regel (key, value) toe aan het woordenboek, waarbij key en value verwijzingen naar objecten zijn.
Public Overridable Sub Remove
(ByVal key As Object) Implements IDictionary.Remove
verwijdert de regel met sleutel=key uit het woordenboek
Public Overridable Sub Clear() 
Implements IDictionary.Clear
maakt het woordenboek leeg
Public Overridable Function ContainsKey
(ByVal key As Object) As Boolean
geeft 'true' terug als de sleutel 'key' in het woordenboek voorkomt.
Public Overridable Function 
ContainsValue(ByVal value As Object) As Boolean
geeft 'true' terug als de waarde 'value' in het woordenboek voorkomt.
Public Overridable ReadOnly Property 
Count As Integer  Implements ICollection.Count
eigenschap: aantal elementen in het woordenboek (sleutel, waarde)
Public Overridable ReadOnly Property 
Keys As ICollection Implements IDictionary.Keys
eigenschap: verzameling van de sleutels van het woordenboek
Public Overridable ReadOnly Property 
Values As ICollection Implements IDictionary.Values
eigenschap: verzameling van de waarden van het woordenboek
Public Overridable Default Property 
Item(ByVal key As Object) As Object  Implements IDictionary.Item
geïndexeerde eigenschap: maakt het mogelijk om de waarde te achterhalen of vast te stellen die aan een sleutel is gekoppeld

Laten we het volgende voorbeeldprogramma eens bekijken:


' opties
Option Strict On
Option Explicit On 

' naamruimten
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}
        ' het woordenboek vullen
        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
        ' aantal elementen in het woordenboek
        Console.Out.WriteLine(("Le dictionnaire a " & dico.Count & " éléments"))
        ' lijst met sleutels
        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
        ' lijst met waarden
        Console.Out.WriteLine("[Liste des valeurs]")
        Dim valeurs As IEnumerator = dico.Values.GetEnumerator()
        While valeurs.MoveNext()
            Console.Out.WriteLine(valeurs.Current)
        End While
        ' lijst met sleutels en waarden
        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
        ' de sleutel "paul" wordt verwijderd
        Console.Out.WriteLine("[Suppression d'une clé]")
        dico.Remove("paul")
        ' lijst met sleutels en waarden
        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

        ' zoeken in het woordenboek
        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
            ' volgende zoekopdracht
            Console.Out.Write("Nom recherché (rien pour arrêter) : ")
            nomCherché = Console.ReadLine().Trim()
        End While
    End Sub
End Module

De uitvoerresultaten zijn als volgt:

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) :

Het programma gebruikt ook een object IEnumerator om door de verzamelingen van sleutels en waarden van het woordenboek van het type ICollection te bladeren (zie hierboven de eigenschappen Keys en Values). Een verzameling is een groep objecten die kan worden doorlopen. De interface ICollection is als volgt gedefinieerd:

Image

Met de eigenschap Count kunnen we het aantal elementen in de verzameling achterhalen. De interface ICollection is afgeleid van de interface IEnumerable:

Image

Deze interface heeft slechts één methode, GetEnumerator, waarmee we een object van het type IEnumerator kunnen verkrijgen:

Image

Met de methode GetEnumerator() van een verzameling ICollection kunnen we de verzameling doorlopen met de volgende methoden:

MoveNext
gaat naar het volgende element van de verzameling. Geeft ‘waar’ (true) terug als dit element bestaat, anders ‘onwaar’ (false). De eerste MoveNext gaat naar het eerste element. Het ‘huidige’ element van de verzameling is dan beschikbaar in de eigenschap Current van de enumerator
Current
eigenschap: huidig element van de verzameling
Reset
zet de iterator terug naar het begin van de verzameling, c.a.d, vóór het eerste element.

De iteratiestructuur voor de elementen van een verzameling (ICollection) in C is dus als volgt:

' de verzameling definiëren
dim C as ICollection C=...
' een enumerator voor deze verzameling ophalen
dim itérateur as IEnumerator=C.GetEnumerator();
' de verzameling doorlopen met deze iterator
while(itérateur.MoveNext())
    ' we hebben een huidig element
     ' itérateur.Current verwerken
end while

4.7. De klasse StreamReader

Met de klasse StreamReader kunt u de inhoud van een bestand lezen. Hieronder volgen enkele van de eigenschappen en methoden:

Public Sub New(ByVal path As String)
opent een stream vanuit het bestand path. Er wordt een uitzondering gegenereerd als het bestand niet bestaat
Overrides Public Sub Close()
sluit de stream
Overrides Public Function ReadLine() As String
leest een regel uit de geopende stream
Overrides Public Function ReadToEnd() As String
leest de rest van de feed vanaf de huidige positie

Hier is een voorbeeld:


' opties
Option Strict On
Option Explicit On 

' naamruimten
Imports System
Imports System.Collections
Imports System.IO

Module test
    Sub Main()
        Dim ligne As String = Nothing
        Dim fluxInfos As StreamReader = Nothing
        ' inhoud van het bestand lezen
        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

en de uitvoerresultaten:

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. De klasse StreamWriter

Met de klasse StreamWriter kunt u naar een bestand schrijven. Hieronder volgen enkele van de eigenschappen en methoden:

Public Sub New(ByVal path As String)
opent een schrijfstream vanuit het bestand path. Er wordt een uitzondering gegenereerd als dit bestand niet kan worden aangemaakt
Public Overridable Property AutoFlush 
As Boolean
als deze waarde waar is, wordt er zonder tussenkomst van een buffer naar de stream geschreven; anders gebeurt het schrijven niet onmiddellijk: er wordt eerst naar een buffer geschreven en pas naar de stream wanneer de buffer vol is. Standaard wordt de gebufferde modus gebruikt. Deze is geschikt voor bestandsstromen, maar over het algemeen niet voor netwerkstromen.
Public Overridable Property NewLine 
As String
om het teken voor het einde van de regel vast te stellen of te achterhalen dat door de methode WriteLine moet worden gebruikt
Overrides Public Sub Close()
sluit de stream
Overloads Public Overridable Sub 
WriteLine(ByVal value As String)
schrijft een regel naar de schrijfstroom
Overrides Public Sub Flush()
schrijft de buffer naar de stream

Laten we het volgende voorbeeld eens bekijken:


' opties
Option Strict On
Option Explicit On 

' naamruimten
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
            ' tekstbestand aanmaken
            fluxInfos = New StreamWriter("infos.txt")
            ' lezen van de via het toetsenbord ingevoerde regel
            Console.Out.Write("ligne (rien pour arrêter) : ")
            ligne = Console.In.ReadLine().Trim()
            ' lus zolang de ingevoerde regel niet leeg is
            While ligne <> ""
                ' regel naar tekstbestand schrijven
                fluxInfos.WriteLine(ligne)
                ' nieuwe regel van het toetsenbord lezen
                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
            ' bestand sluiten
            Try
                fluxInfos.Close()
            Catch
            End Try
        End Try
    End Sub
End Module

en de uitvoerresultaten:

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. De klasse Regex

De klasse Regex maakt het gebruik van reguliere expressies mogelijk. Hiermee kan het formaat van een tekenreeks worden getoetst. Zo kan worden gecontroleerd of een tekenreeks die een datum weergeeft, daadwerkelijk de indeling dd/mm/jj heeft. Hiervoor wordt een patroon gebruikt en wordt de tekenreeks met dit patroon vergeleken. In dit voorbeeld moeten j, m en a dus cijfers zijn. Het patroon voor een geldige datumnotatie is dan "\d\d/\d\d/\d\d", waarbij het symbool \d een cijfer aangeeft. De volgende symbolen kunnen in een patroon worden gebruikt (Microsoft-documentatie):

 
Beschrijving
\ 
Markeert het volgende teken als een speciaal teken of letterlijk teken. Bijvoorbeeld: "n" komt overeen met het teken "n". "\n" komt overeen met een nieuwe regel. De reeks "\\" komt overeen met "\", terwijl "\(" overeenkomt met "(".
^ 
Komt overeen met het begin van de invoer.
$ 
Komt overeen met het einde van de invoer.
* 
Komt nul of meerdere keren overeen met het voorgaande teken. Zo komt "zo*" overeen met "z" of met "zoo".
+ 
Komt één of meerdere keren overeen met het voorgaande teken. Zo komt "zo+" overeen met "zoo", maar niet met "z".
? 
Komt overeen met het voorgaande teken nul of één keer. Bijvoorbeeld: "a?ve?" komt overeen met "ve" in "lever".
.
Komt overeen met elk willekeurig teken, behalve het regeleinde-teken.

(modèle) 
Zoek naar modèle en sla de overeenkomst op. De overeenkomende subreeks kan uit de verkregen verzameling Matches worden gehaald met behulp van Item [0]...[n]. Om overeenkomsten te vinden met tekens tussen haakjes ( ), gebruikt u "\(" of "\)".

x|y
Komt overeen met x of met y. Bijvoorbeeld: "z|foot" komt overeen met "z" of met "foot". "(z|f)oo" komt overeen met "zoo" of met "foo".

{n}
n is een niet-negatief geheel getal. Komt exact overeen met n maal het teken. Bijvoorbeeld: "o{2}" komt niet overeen met "o" in "Bob," maar met de eerste twee "o" in "fooooot".

{n,} 
n is een niet-negatief geheel getal. Komt overeen met ten minste n keer het teken. Bijvoorbeeld: "o{2,}" komt niet overeen met "o" in "Bob", maar met alle "o" in "fooooot". "o{1,}" is gelijk aan "o+" en "o{0,}" is gelijk aan "o*".

{n,m} 
m en n zijn niet-negatieve gehele getallen. Komt overeen met ten minste n en ten hoogste m keer het teken. Bijvoorbeeld: "o{1,3}" komt overeen met de eerste drie "o" in "foooooot" en "o{0,1}" staat gelijk aan "o?".

[xyz] 
Tekenset. Komt overeen met een van de opgegeven tekens. Bijvoorbeeld: "[abc]" komt overeen met "a" in "plat".

[^xyz] 
Negatieve tekenset. Komt overeen met elk teken dat niet is opgegeven. Bijvoorbeeld: "[^abc]" komt overeen met "p" in "plat".

[a-z] 
Tekenreeks. Komt overeen met elk teken in de opgegeven reeks. Bijvoorbeeld: "[a-z]" komt overeen met elk klein letterteken tussen "a" en "z".

[^m-z] 
Negatief tekenbereik. Komt overeen met elk teken dat niet in de opgegeven reeks voorkomt. Bijvoorbeeld: "[^m-z]" komt overeen met elk teken dat niet tussen "m" en "z" voorkomt.
\b 
Komt overeen met een grens die een woord vertegenwoordigt, met andere woorden, de positie tussen een woord en een spatie. Bijvoorbeeld: "er\b" komt overeen met "er" in "lever", maar niet met "er" in "verbe".
\B 
Komt overeen met een grens die geen woord vertegenwoordigt. "en*t\B" komt overeen met "ent" in "bien entendu".
\d 
Komt overeen met een teken dat een cijfer vertegenwoordigt. Komt overeen met [0-9].
\D 
Komt overeen met een teken dat geen cijfer vertegenwoordigt. Is gelijk aan [^0-9].
\f 
Komt overeen met een pagina-einde-teken.
\n 
Komt overeen met een regeleinde-teken.
\r 
Komt overeen met een carriage return-teken.
\s 
Komt overeen met alle witruimte, inclusief spatie, tab, pagina-einde, enz. Komt overeen met "[ \f\n\r\t\v]".
\S 
Komt overeen met elk niet-wit spatiekarakter. Komt overeen met "[^ \f\n\r\t\v]".
\t 
Komt overeen met een tabteken.
\v 
Komt overeen met een verticaal tabteken.
\w 
Komt overeen met elk teken dat een woord vertegenwoordigt en een onderstrepingsteken bevat. Komt overeen met "[A-Za-z0-9_]".
\W 
Komt overeen met elk teken dat geen woord vertegenwoordigt. Komt overeen met "[^A-Za-z0-9_]".

\num 
Komt overeen met num, waarbij num een positief geheel getal is. Verwijst naar opgeslagen toewijzingen. Bijvoorbeeld: "(.)\1" komt overeen met twee opeenvolgende identieke tekens.

\n
Komt overeen met n, waarbij n een octale escape-waarde is. Octale escape-waarden moeten uit 1, 2 of 3 cijfers bestaan. Bijvoorbeeld: "\11" en "\011" komen beide overeen met een tab-teken. "\0011" is gelijk aan "\001" & "1". Octale escape-waarden mogen niet hoger zijn dan 256. Als dat wel het geval is, worden alleen de eerste twee cijfers in de uitdrukking meegenomen. Hiermee kunnen de codes ASCII in reguliere uitdrukkingen worden gebruikt.

\xn
Komt overeen met n, waarbij n een hexadecimale escape-waarde is. Hexadecimale escape-waarden moeten verplicht uit twee cijfers bestaan. Bijvoorbeeld: "\x41" komt overeen met "A". "\x041" is gelijk aan "\x04" & "1". Hiermee kunnen de codes ASCII in reguliere expressies worden gebruikt.

Een element in een sjabloon kan één of meerdere keren voorkomen. Laten we enkele voorbeelden bekijken rond het symbool \d, dat één cijfer vertegenwoordigt:

model
betekenis
\d
een cijfer
\d?
0 of 1 cijfer
\d*
0 of meer cijfers
\d+
1 of meer cijfers
\d{2}
2 cijfers
\d{3,}
minstens 3 cijfers
\d{5,7}
tussen 5 en 7 cijfers

Laten we ons nu het model voorstellen dat het verwachte formaat voor een tekenreeks kan beschrijven:

gezochte tekenreeks
model
une date au format jj/mm/aa
\d{2}/\d{2}/\d{2}
une heure au format hh:mm:ss
\d{2}:\d{2}:\d{2}
un nombre entier non signé
\d+
un suite d'espaces éventuellement vide
\s*
un nombre entier non signé qui peut être précédé ou suivi d'espaces
\s*\d+\s*
un nombre entier qui peut être signé et précédé ou suivi d'espaces
\s*[+|-]?\s*\d+\s*
un nombre réel non signé qui peut être précédé ou suivi d'espaces
\s*\d+(.\d*)?\s*
un nombre réel qui peut être signé et précédé ou suivi d'espaces
\s*[+|]?\s*\d+(.\d*)?\s*
une chaîne contenant le mot juste
\bjuste\b
  

Je kunt aangeven waar in de tekenreeks naar het patroon wordt gezocht:

patroon
betekenis
^modèle
het sjabloon begint de tekenreeks
modèle$
het sjabloon eindigt de tekenreeks
^modèle$
het sjabloon begint en eindigt de tekenreeks
modèle
het patroon wordt overal in de tekenreeks gezocht, te beginnen bij het begin ervan.
gezochte tekenreeks
patroon
une chaîne se terminant par un point d'exclamation
!$
une chaîne se terminant par un point
\.$
une chaîne commençant par la séquence //
^//
une chaîne ne comportant qu'un mot éventuellement suivi ou précédé d'espaces
^\s*\w+\s*$
une chaîne ne comportant deux mot éventuellement suivis ou précédés d'espaces
^\s*\w+\s*\w+\s*$
une chaîne contenant le mot secret
\bsecret\b

De deelverzamelingen van een patroon kunnen worden "opgehaald". Zo kan niet alleen worden gecontroleerd of een tekenreeks overeenkomt met een bepaald patroon, maar kunnen ook de elementen in die tekenreeks worden opgehaald die overeenkomen met de deelverzamelingen van het patroon die tussen haakjes zijn geplaatst. Als we bijvoorbeeld een tekenreeks analyseren die een datum dd/mm/jj bevat en we willen bovendien de elementen dd, mm en jj van deze datum ophalen, dan gebruiken we het patroon (\d\d)/(\d\d)/(\d\d).

4.9.1. Controleren of een tekenreeks overeenkomt met een bepaald patroon

Een object van het type Regex wordt als volgt opgebouwd:

Public Sub New(ByVal pattern As String)

De constructor maakt een „reguliere expressie”-object aan op basis van een als parameter doorgegeven patroon (pattern). Zodra de reguliere expressie is aangemaakt, kan deze worden vergeleken met tekenreeksen met behulp van de methode IsMatch:

Overloads Public Function IsMatch(ByVal input As String) As Boolean

IsMatch retourneert 'waar' als de invoerreeks overeenkomt met het patroon van de reguliere expressie. Hier volgt een voorbeeld:


' opties
Option Strict On
Option Explicit On 

' naamruimten
Imports System
Imports System.Collections
Imports System.Text.RegularExpressions

Module regex1

    Sub Main()
        ' een reguliere expressie als sjabloon
        Dim modèle1 As String = "^\s*\d+\s*$"
        Dim regex1 As New Regex(modèle1)
        ' een exemplaar vergelijken met het patroon
        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

    ' weergeven 
    Sub affiche(ByVal msg As String)
        Console.Out.WriteLine(msg)
    End Sub
End Module

en de uitvoerresultaten:

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. Zoek alle elementen in een tekenreeks die aan een patroon voldoen

De methode Matches

Overloads Public Function Matches(ByVal input As String) As MatchCollection

levert een verzameling elementen uit de tekenreeks input op die aan het patroon voldoen, zoals in het volgende voorbeeld te zien is:


' opties
Option Strict On
Option Explicit On 

' naamruimten
Imports System
Imports System.Collections
Imports System.Text.RegularExpressions

Module regex2
    Sub Main()
        ' meerdere voorkomens van het sjabloon in het exemplaar
        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

    'weergeven
    Sub affiche(ByVal msg As String)
        Console.Out.WriteLine(msg)
    End Sub
End Module

De klasse MatchCollection heeft een eigenschap Count die het aantal elementen in de verzameling aangeeft. Als résultats een object is van het type MatchCollection, dan is résultats(i) het i-de element van deze verzameling en is het van het type Match. In ons voorbeeld is résultats de verzameling van elementen van de reeks exemplaire3 die overeenkomen met het model modèle2, en is résultats(i) een van deze elementen. De klasse Match heeft twee eigenschappen die hier voor ons van belang zijn:

  • Value: de waarde van het Match-object, dus het element dat overeenkomt met het model
  • Index: de positie waar het element is gevonden in de doorzochte tekenreeks

De resultaten van de uitvoering van het vorige programma:

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. Delen van een patroon ophalen

Deelverzamelingen van een patroon kunnen worden "opgehaald". Zo kan niet alleen worden gecontroleerd of een tekenreeks overeenkomt met een bepaald patroon, maar kunnen ook de elementen uit die tekenreeks worden opgehaald die overeenkomen met de deelverzamelingen van het patroon die tussen haakjes zijn geplaatst. Als we dus een tekenreeks analyseren die een datum dd/mm/jj bevat en we willen bovendien de elementen dd, mm en jj van deze datum ophalen, dan gebruiken we het patroon (\d\d)/(\d\d)/(\d\d). Laten we het volgende voorbeeld eens bekijken:


' opties
Option Strict On
Option Explicit On 

' naamruimten
Imports System
Imports System.Collections
Imports System.Text.RegularExpressions

Module regex2
    Sub Main()
        ' elementen in het model vastleggen
        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"
        ' controle van het sjabloon
        Dim résultat As Match = regex3.Match(exemplaire4)
        If résultat.Success Then
            ' het exemplaar komt overeen met het sjabloon
            affiche(("L'exemplaire [" + exemplaire4 + "] correspond au modèle [" + modèle3 + "]"))
            ' de groepen worden weergegeven
            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
            ' het exemplaar komt niet overeen met het sjabloon
            affiche(("L'exemplaire[" + exemplaire4 + " ne correspond pas au modèle [" + modèle3 + "]"))
        End If
    End Sub

    'geeft weer
    Sub affiche(ByVal msg As String)
        Console.Out.WriteLine(msg)
    End Sub
End Module

De uitvoering van dit programma levert de volgende resultaten op:

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

De wijziging zit in het volgende stukje code:


        ' sjablooncontrole
        Dim résultat As Match = regex3.Match(exemplaire4)
        If résultat.Success Then
            ' het exemplaar komt overeen met het sjabloon
            affiche(("L'exemplaire [" + exemplaire4 + "] correspond au modèle [" + modèle3 + "]"))
            ' de groepen worden weergegeven
            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

De tekenreeks exemplaire4 wordt vergeleken met het sjabloon regex3 via de methode Match. Deze methode retourneert een object Match dat al eerder is geïntroduceerd. We gebruiken hier twee nieuwe eigenschappen van deze klasse:

  • Success: geeft aan of er een overeenkomst is gevonden
  • Groups: verzameling waarin
    • Groups[0] overeenkomt met het deel van de tekenreeks dat overeenkomt met het patroon
    • Groups[i] (i>=1) overeenkomt met de groep haakjes nr. i

Als het resultaat van het type Match is, dan is résultats.Groups van het type GroupCollection en is résultats.Groups[i] van het type Group. De klasse Group heeft twee eigenschappen die we hier gebruiken:

  • Value: de waarde van het Group-object waarvan het element overeenkomt met de inhoud van een haakje
  • Index: de positie waar het element is gevonden in de doorzochte tekenreeks

4.9.4. Een oefenprogramma

Het vinden van de reguliere expressie waarmee we kunnen controleren of een tekenreeks wel degelijk overeenkomt met een bepaald patroon, is soms een echte uitdaging. Met het volgende programma kun je oefenen. Het vraagt om een patroon en een tekenreeks en geeft vervolgens aan of de tekenreeks al dan niet overeenkomt met het patroon.


' opties
Option Strict On
Option Explicit On 

' naamruimten
Imports System
Imports System.Collections
Imports System.Text.RegularExpressions
Imports Microsoft.visualbasic

Module regex4
    Sub Main()
        ' een reguliere expressie als sjabloon
        Dim modèle, chaine As String
        Dim regex As Regex = Nothing
        Dim résultats As MatchCollection
        ' de gebruiker wordt gevraagd welke sjablonen en exemplaren met dit exemplaar moeten worden vergeleken
        Dim terminé1 As Boolean = False
        Do While Not terminé1
            Dim erreur As Boolean = True
            Do While Not terminé1 And erreur
                ' er wordt gevraagd om het sjabloon
                Console.Out.Write("Tapez le modèle à tester ou fin pour arrêter :")
                modèle = Console.In.ReadLine()
                ' klaar?
                If modèle.Trim().ToLower() = "fin" Then
                    terminé1 = True
                Else
                    ' de reguliere expressie wordt aangemaakt
                    Try
                        regex = New Regex(modèle)
                        erreur = False
                    Catch ex As Exception
                        Console.Error.WriteLine(("Erreur : " + ex.Message))
                    End Try
                End If
            Loop
            ' klaar?
            If terminé1 Then Exit Sub
            ' de gebruiker wordt gevraagd welke exemplaren met het model moeten worden vergeleken
            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()
                ' klaar?
                If chaine.Trim().ToLower() = "fin" Then
                    terminé2 = True
                Else
                    ' we voeren de vergelijking uit
                    résultats = regex.Matches(chaine)
                    ' geslaagd?
                    If résultats.Count = 0 Then
                        Console.Out.WriteLine("Je n'ai pas trouvé de correspondances")
                    Else
                        ' de elementen die overeenkomen met het sjabloon worden weergegeven
                        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))
                            ' subelementen
                            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

    'geeft weer
    Sub affiche(ByVal msg As String)
        Console.Out.WriteLine(msg)
    End Sub
End Module

Hier volgt een voorbeeld van de uitvoering:

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. De methode Split

We zijn deze methode al tegengekomen in de klasse String:

Overloads Public Function Split(ByVal ParamArray separator() As Char) As String()

De tekenreeks wordt gezien als een reeks velden, gescheiden door de tekens die in de tabel [separator] staan. Het resultaat is de tabel met deze velden.

Het veldscheidingsteken van de tekenreeks is hier een van de tekens uit de tabel separator. Met de methode Split van de klasse Regex kunnen we het scheidingsteken op basis van een patroon specificeren:

Overloads Public Function Split(ByVal input As String) As String()

De tekenreeks [input] wordt opgesplitst in velden, die worden gescheiden door een scheidingsteken dat overeenkomt met het sjabloon van het huidige object Regex. Stel bijvoorbeeld dat we in een tekstbestand regels hebben in de vorm veld1, veld2, …, veldn. De velden worden gescheiden door een komma, maar deze kan worden voorafgegaan of gevolgd door spaties. De methode Split van de klasse string is dan niet geschikt. De methode RegEx biedt de oplossing. Als ligne de gelezen regel is, kunnen de velden worden verkregen via

dim champs() as string=new Regex("s*,\s*").Split(ligne)

zoals het volgende voorbeeld laat zien:


' opties
Option Strict On
Option Explicit On 

' naamruimten
Imports System
Imports System.Text.RegularExpressions

Module regex5
    Sub Main()
        ' een regel
        Dim ligne As String = "abc  , def  , ghi"
        ' een sjabloon
        Dim modèle As New Regex("\s*,\s*")
        ' regels opsplitsen in velden
        Dim champs As String() = modèle.Split(ligne)
        ' weergave
        Dim i As Integer
        For i = 0 To champs.Length - 1
            Console.Out.WriteLine(("champs[" & i & "]=[" & champs(i) & "]"))
        Next i
    End Sub
End Module

De uitvoerresultaten:

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. De klassen BinaryReader en BinaryWriter

De klassen BinaryReader en BinaryWriter worden gebruikt om binaire bestanden te lezen en te schrijven. Laten we eens kijken naar de volgende toepassing. We willen een programma schrijven dat als volgt zou worden aangeroepen:

// syntaxis pg tekst bin
// een tekstbestand (tekst) wordt ingelezen en de inhoud ervan wordt opgeslagen in een
// binair bestand
// het tekstbestand bevat regels in de vorm naam : leeftijd
// die in een structuur met string en int worden opgeslagen

Het tekstbestand bevat het volgende:

paul : 10
helene : 15
jacques : 11
sylvain : 12

Het programma ziet er als volgt uit:


' opties
Option Strict On
Option Explicit On 

' naamruimten
Imports System
Imports System.Text.RegularExpressions
Imports System.IO

' BinaryWriter()

Module bw1
    ' syntaxis pg tekst bin
    ' een tekstbestand (tekst) wordt gelezen en de inhoud ervan wordt opgeslagen in een
    ' binair bestand
    ' het tekstbestand bevat regels in de vorm naam : leeftijd
    ' die we opslaan in een structuur met string en int

    Sub Main(ByVal arguments() As String)
        ' er zijn 2 argumenten nodig
        Dim nbArgs As Integer = arguments.Length
        If nbArgs <> 2 Then
            Console.Error.WriteLine("syntaxe : pg texte binaire")
            Environment.Exit(1)
        End If
        ' het tekstbestand openen in leesmodus
        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
        ' het binaire bestand openen om te schrijven
        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
        ' tekstbestand lezen - binair bestand schrijven
        ' regel uit het tekstbestand
        Dim ligne As String
        ' het scheidingsteken van de velden in de regel
        Dim séparateur As New Regex("\s*:\s*")
        ' het leeftijdsmodel
        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
            ' lege regel?
            If ligne.Trim() = "" Then
                traitementFini = True
            End If
            ' nog een regel
            If Not traitementFini Then
                numLigne += 1
                ' een regel met naam: leeftijd
                champs = séparateur.Split(ligne)
                ' we hebben 2 velden nodig
                If champs.Length <> 2 Then
                    Console.Error.WriteLine(("La ligne n° " & numLigne & " du fichier " & arguments(0) & " a un nombre de champs incorrect"))
                    ' volgende regel
                    traitementFini = True
                End If
            End If
            If Not traitementFini Then
                ' het tweede veld moet een geheel getal zijn >=0
                If Not modAge.IsMatch(champs(1)) Then
                    Console.Error.WriteLine(("La ligne n° " & numLigne & " du fichier " & arguments(0) & " a un âge incorrect"))
                    ' volgende regel
                    traitementFini = True
                End If
                ' we schrijven de gegevens naar het binaire bestand
                output.Write(champs(0))
                output.Write(Integer.Parse(champs(1)))
            End If
            'volgende regel
            ligne = input.ReadLine()
        End While
        ' bestanden sluiten
        input.Close()
        output.Close()
    End Sub
End Module

Laten we even stilstaan bij de bewerkingen met betrekking tot de klasse BinaryWriter:

  • het object BinaryWriter wordt geopend door de bewerking

            output = New BinaryWriter(New FileStream(arguments(1), FileMode.Create, FileAccess.Write))

Het argument van de constructor moet een stream zijn. Hier gaat het om een stream die is opgebouwd uit een bestand (FileStream) waarvan we het volgende opgeven:

  • (vervolg)
    • de naam
    • de uit te voeren bewerking, hier FileMode.Create om het bestand aan te maken
    • het type toegang, hier FileAccess.Write voor schrijftoegang tot het bestand
  • de schrijfbewerking

                 ' de gegevens worden naar het binaire bestand geschreven
                output.Write(champs(0))
                output.Write(Integer.Parse(champs(1)))

De klasse BinaryWriter beschikt over verschillende overladen methoden Write om de verschillende soorten eenvoudige gegevens te schrijven

  • de bewerking voor het sluiten van de stream
        output.Close()

De resultaten van de vorige uitvoering worden ons door het volgende programma verstrekt. Dit programma accepteert ook twee argumenten:

     ' syntaxis pg bin tekst
     ' een binair bestand (bin) wordt gelezen en de inhoud ervan wordt opgeslagen in een tekstbestand (tekst)
     ' het binaire bestand heeft een structuur van het type string, int
     ' het tekstbestand bevat regels in de vorm naam : leeftijd

We voeren dus de omgekeerde bewerking uit. We lezen een binair bestand in om een tekstbestand te maken. Als het gegenereerde tekstbestand identiek is aan het oorspronkelijke bestand, weten we dat de conversie tekst --> binair --> tekst goed is verlopen. De code is als volgt:


' opties
Option Strict On
Option Explicit On 

' naamruimten
Imports System
Imports System.Text.RegularExpressions
Imports System.IO

Module br1
    ' syntaxis pg bin tekst
    ' we lezen een binair bestand bin en slaan de inhoud ervan op in een tekstbestand (tekst)
    ' het binaire bestand heeft een structuur van het type string, int
    ' het tekstbestand bevat regels in de vorm naam : leeftijd

    Sub Main(ByVal arguments() As String)
        ' er zijn 2 argumenten nodig
        Dim nbArgs As Integer = arguments.Length
        If nbArgs <> 2 Then
            Console.Error.WriteLine("syntaxe : pg binaire texte")
            Environment.Exit(1)
        End If
        ' het binaire bestand wordt geopend om te lezen
        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
        ' het tekstbestand openen om te schrijven
        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
        ' binair bestand lezen – tekstbestand schrijven
        Dim nom As String        ' nom d'une personne
        Dim age As Integer        ' son âge
        ' verwerkingslus voor het binaire bestand
        While True
            ' naam lezen
            Try
                nom = dataIn.ReadString()
            Catch
                ' einde van het bestand
                Exit Sub
            End Try
            ' lezen van leeftijd
            Try
                age = dataIn.ReadInt32()
            Catch
                Console.Error.WriteLine("Le fichier " & arguments(0) + " ne semble pas avoir un format correct")
                Exit Sub
            End Try
            ' schrijven naar tekstbestand
            dataOut.WriteLine(nom & ":" & age)
            System.Console.WriteLine(nom & ":" & age)
        End While
        ' alles sluiten
        dataIn.Close()
        dataOut.Close()
    End Sub
End Module

Laten we even stilstaan bij de bewerkingen met betrekking tot de klasse BinaryReader:

  • het object BinaryReader wordt geopend door de bewerking

            dataIn = New BinaryReader(New FileStream(arguments(0), FileMode.Open, FileAccess.Read))

Het argument van de constructor moet een stream zijn. Hier gaat het om een stream die is opgebouwd uit een bestand (FileStream) waarvan we het volgende opgeven:

  • (vervolg)
    • de naam
    • de uit te voeren bewerking, hier FileMode.Open om een bestaand bestand te openen
    • het type toegang, hier FileAccess.Read voor leestoegang tot het bestand
  • de leesbewerking
                nom = dataIn.ReadString()
                age = dataIn.ReadInt32()

De klasse BinaryReader beschikt over verschillende methoden, zoals ReadXX, om de verschillende soorten eenvoudige gegevens te lezen

  • de bewerking om de stream te sluiten
        dataIn.Close()

Als we de twee programma's achter elkaar uitvoeren, waarbij personnes.txt wordt omgezet in personnes.bin en vervolgens personnes.bin in personnes.txt2, krijgen we:

dos>more personnes.txt
paul : 10
helene : 15
jacques : 11
sylvain : 12

dos>more personnes.txt2
paul:10
helene:15
jacques:11
sylvain:12

dos>dir
29/04/2002  18:19                   54 personnes.txt
29/04/2002  18:19                   44 personnes.bin
29/04/2002  18:20                   44 personnes.txt2