Reguliere Expressies in C#

  1. Inleiding
  2. Een eerste voorbeeld
  3. Een tweede voorbeeld
  4. Slot
  5. Voorbeeldprogramma

Inleiding

Data moet wel eens aan bepaalde voorwaarden voldoen en reguliere expressies kunnen gebruikt worden voor het valideren en het filteren van de data. Je kunt binnen C# met reguliere expressies werken want C# ondersteunt ook reguliere expressies.

C# is niet de enige programmeertaal die met reguliere expressies kan werken. Andere programmeertalen doen dat ook en je kan reguliere expressies ook toepassen in bijvoorbeeld JavaScript en Java. Bij een reguliere expressie ga je uit van een bepaald patroon. De te evalueren tekst moet dan voldoen aan dat patroon en de patroon leg je vast in een reguliere expressie.

up | down

Een eerste voorbeeld

Laten we beginnen met een eenvoudig voorbeeld om te zien wat reguliere expressies zijn en hoe we ze kunnen gebruiken. We zetten de namen van een aantal vruchten in een string:

string stringWaarde1 = "abrikoos aardbei ananas appel";

De string bevat nu vruchten en we willen de vruchten zien die voldoen aan de volgende criteria:
1) de naam moet beginnen met een ‘a’
2) de naam moet eindigen op een ‘s’.
We maken naar aanleiding van de criteria een reguliere expressie en die ziet er als volgt uit:

string reguliereExpressie1 = @"a\w+s"; 

We zien het volgende patroon als we de reguliere expressie gaan analyseren:

  1. De a staat voor alles in de string wat begint met een “a”. Dat is de eerste voorwaarde voor datgene wat in de string staat. Het moet met een “a” beginnen.
  2. De \w+ is de tweede voorwaarde. Je gaat door naar de volgende ronde als na de “a” word characters volgen. Word characters zijn letters (zowel hoofd als kleine letters) , getallen en tekens zoals de “-” en de “_”, maar niet de spatie.
  3. Ten slotte de derde en laatste voorwaarde. Wat in de string staat, dat moet eindigen op een s.

Er vindt aan de hand van de reguliere expressie een soort filtering plaats en in de MatchCollection komt alles te staan wat voldoet aan de opgestelde criteria:

MatchCollection gevondenMatches = 
Regex.Matches(stringWaarde1, reguliereExpressie1);

En de MatchCollection kunnen we als volgt doorlopen:

foreach (Match match in gevondenMatches)
{
  Console.WriteLine("->" + match.Value);
}

Getoond worden de abrikoos en de ananas omdat de desbetreffende vruchten beginnen met een “a” en en eindigen op een “s” en alles tussen de “a” en de “s” word characters zijn.

up | down

Een tweede voorbeeld

We hadden in het vorige voorbeeld gezien hoe we reguliere expressies kunnen toepassen als zijnde een filter waarbij we de goedgekeurde dingen doorlaten. We gaan nu een reguliere expressie gebruiken als zijnde een filter dat dingen tegenhoudt. We mogen alleen verder als aan de criteria is voldaan.

Laten we de Nederlandse postcode als casus gebruiken. De Nederlandse postcode is samengesteld uit numerieke karakters en alfanumerieke karakters met een spatie in het midden, bijvoorbeeld 1234 AB. We definiëren de te toetsen string en de reguliere expressie:

string stringWaarde2 = "1234 AB";
string reguliereExpressie2 = 
@"^\d{4}[\s{1}]?[A-Z,a-z]{2}$";

We gaan de reguliere expressie analyseren en we zien het volgende patroon:

  1. De reguliere expressie begint met een ^
    De ^ geeft aan dat we gaan kijken naar het begin van de te evalueren string.

  2. De te evalueren string moet beginnen met numerieke karakters: ^\d

  3. Het aantal numerieke karakters waarmee de string moet beginnen is vier: ^\d{4}

  4. Na de numerieke karakters mag een spatie komen, maar dat mag er niet meer zijn dan één: ^\d{4}[\s{1}]

  5. De spatie in het midden mag, maar is niet verplicht, dus we voegen een ? toe: ^\d{4}[\s{1}]?

  6. Na de (eventuele) spatie mogen maximaal twee alfanumerieke karakters komen: ^\d{4}[\s{1}]?[A-Z,a-z]{2}

  7. De postcode moet eindigen op die twee alfanumerieke karakters en dat brengen we tot uiting via de $ waardoor de reguliere expressie uiteindelijk dit wordt: ^\d{4}[\s{1}]?[A-Z,a-z]{2}$

We doen als volgt de evaluatie waarbij we gebruik maken van de reguliere expressie:

string stringWaarde2 = "1234 AB";
string reguliereExpressie2 = 
@"^\d{4}[\s{1}]?[A-Z,a-z]{2}$";
Regex objRegex = new Regex(reguliereExpressie2);

if (objRegex.IsMatch(stringWaarde2))
{
  Console.WriteLine("Stringwaarde '" + 
  stringWaarde2 + "':" +
  " kan als Nederlandse postcode 
    gebruikt worden.\r\n");
}
else 
{
   Console.WriteLine("Stringwaarde '" + 
   stringWaarde2  + "':" +
   " kan NIET als Nederlandse postcode 
     gebruikt worden.\r\n");   
}

En we zien dat de postcodes 1234 AB en 1234AB door de evaluatie heenkomen, maar de waarde ABCD 12 niet.

up | down

Slot

Zo… begint het al te duizelen? Ik hoop van niet, want ik heb geprobeerd het zo simpel mogelijk te houden voor zover dat mogelijk is met reguliere expressies.

Het grote voordeel van reguliere expressies is dat ze zeer krachtig en compact zijn. Een gewone expressie heeft er misschien meerdere pagina’s aan code voor nodig terwijl een reguliere expressie met één verbatim string de klus ook kan klaren.

Maar elk voordeel heeft zijn nadeel. We gaan voor het betere werk en we maken bijvoorbeeld een reguliere expressie dat evalueert of een waarde gebruikt kan worden als email adres:

string reguliereExpressie3 = 
@"^([a-zA-Z0-9_\-\.]+)@((\[[0-9]{1,3}\.[0-9]{1,3}
\.[0-9]{1,3}\.)|(([a-zA-Z0-9\-]+\.)+))
([a-zA-Z]{2,4}|[0-9]{1,3})(\]?)$";

Lekker compact, maar wat als er iets aangepast moet worden aan de reguliere expressie? Ik moet toegeven dat ik niet enthousiast word van complexe reguliere expressie en ik ga ze graag uit de weg. Ik twijfel er echter niet aan dat andere programmeurs wel de nodige arbeidsvreugd zullen vinden in het debuggen van complexe reguliere expressies of arbeidsvreugd zullen vinden in het afschuiven van dat soort klussen op nietsvermoedende nieuwe collega’s.

Ik heb twee eenvoudige voorbeeldjes gegeven, maar er kan nog heel veel meer met reguliere expressies. Wil je meer weten? Zoek dan op het internet op Regular Expression en je zult veel websites vinden die in detail uitleggen welke tekens je allemaal in een reguliere expressie kan opnemen en wat die tekens doen.

Hopelijk ben je met deze posting weer wat wijzer geworden en ik hoop je weer terug te zien in één van mijn volgende blog posts. Wil je weten wat ik nog meer over C# heb geschreven? Hit the C# button…

up | down


Voorbeeldprogramma

using System;
using System.Text.RegularExpressions;

namespace ReguliereExpressies
{
  class MainClass
    public static void Main(string[] args)
    {
         // de string die we gaan onderzoeken
         string stringWaarde1 = 
         "abrikoos aardbei ananas appel";
         // de reguliere expressie
         // alle woorden die beginnen 
         // met een a en eindigen op een s
         string reguliereExpressie1 = @"a\w+s"; 
         
         // Zoek in de string wat voldoet 
         MatchCollection gevondenMatches = 
         Regex.Matches(stringWaarde1, 
                       reguliereExpressie1);
         // doorloop en toon
         Console.WriteLine(
         "Te onderzoeken string : " + 
         stringWaarde1);
         Console.WriteLine(
         "Reguliere Expressie   : " + 
         reguliereExpressie1);
         Console.WriteLine(
         "\r\nWoorden in de string
         die aan de expressie voldoen:");
         foreach (Match match in gevondenMatches)
         {
           Console.WriteLine("->" + match.Value);
         }
         Console.WriteLine("Omdat ze beginnen 
         met een 'a' en eindigen op een 's'.\r\n");
         
         // Regex object 2
         string stringWaarde2 = "1234 AB";
         string reguliereExpressie2 = 
         @"^\d{4}[\s{1}]?[A-Z,a-z]{2}$";
         Console.WriteLine(
         "Te onderzoeken string : " + 
         stringWaarde2);
         Console.WriteLine(
         "Reguliere Expressie   : " + 
         reguliereExpressie2);
         Regex objRegex = 
         new Regex(reguliereExpressie2);
         if (objRegex.IsMatch(stringWaarde2))
         {
           Console.WriteLine("Stringwaarde '" + 
           stringWaarde2 + "':" +
           " kan als Nederlandse postcode 
           gebruikt worden.\r\n");
         }
         else 
         {
           Console.WriteLine("Stringwaarde '" + 
           stringWaarde2  + "':" +
           " kan NIET als Nederlandse postcode 
           gebruikt worden.\r\n");   
         }

         // Regex object 3
         string stringWaarde3 = "test@outlook.com";
         string reguliereExpressie3 = 
         @"^([a-zA-Z0-9_\-\.]+)
         @((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.)|
         (([a-zA-Z0-9\-]+\.)+))([a-zA-Z]
         {2,4}|[0-9]{1,3})(\]?)$";
         objRegex = 
         new Regex(reguliereExpressie3);
         if (objRegex.IsMatch(stringWaarde3))
         {
           Console.WriteLine(
           "Stringwaarde '" + stringWaarde3 +
           "' kan als emailadres gebruikt worden.");
           Console.WriteLine(
           "omdat aan deze expressie wordt voldaan:");
           Console.WriteLine(
           reguliereExpressie3 + Environment.NewLine);
         }
    }
}

up

Laat een reactie achter

Je e-mailadres wordt niet gepubliceerd. Vereiste velden zijn gemarkeerd met *