RegEx in PowerShell: Treffer in Variablen speichern mit Named Groups

    Reguläre Ausdrücke (RegEx) in PowerShellPowerShell erlaubt den Einsatz von regulären Ausdrücken in verschiedenen Kontexten, unter anderem mit den Operatoren match und replace. Bei langen Ausdrücken kann es hilfreich sein, den Inhalt von Gruppen in Variablen mit einem sprechenden Namen zu speichern.

    Nach der Auswertung eines regulären Ausdrucks legt PowerShell die Fundstellen in einem Array namens $matches ab. Im ersten Element [0] findet sich die Zeichenkette, auf die das ganze Muster gepasst hat. Verwendet man Gruppen, dann legt PowerShell in den weiteren Elementen von $matches die darauf zutreffenden Teile des ursprünglichen Strings ab:

    (gci .\Rechnung-08-17.xls) -match "Rechnung-(\d\d)-(\d\d)"

    Dieses Beispiel geht davon aus, dass Excel-Dateien existieren, die nach dem Muster "Rechnung"- + Monat + "-" + Jahr + ".xls" benannt wurden. Wenn man mit Hilfe von Get-ChildItem die Datei "Rechnung-08-17.xls" anzeigt, dann besteht die Aufgabe darin, von dort den Monat und das Jahr zu extrahieren.

    Dafür verwendet man so genannte Groups, die im obigen Beispiel jeweils mit "(\d\d)" das Vorkommen von zweistelligen Zahlen abfragen. Das Ergebnis des Kommandos ist true und anschließend enthält $matches[1] "08" und $matches[2] "17".

    Anstatt mit einem Array zu hantieren, kann man an die Gruppen Namen vergeben, die man anschließend als Index zu einem Hashtable nutzt:

    (gci .\Rechnung-08-17.xls) -match "Rechnung-(?<monat>\d\d)-(?<jahr>\d\d)"

    Das Muster ist das gleiche wie oben. Der Unterschied besteht nur darin, dass ihm ein "?<monat>" bzw. ein "?<jahr>" vorangestellt wird. Anschließend kann man auf die Fundstellen mit

    $matches.monat

    bzw.

    $matches.jahr

    zugreifen und diese bei Bedarf weiter verarbeiten.

    Suchen und Ersetzen mit regulären Ausdrücken und Named Groups in PowerShell.

    Named Groups für das Suchen und Ersetzen mit PowerShell

    Noch praktischer sind Named Groups beim Ersetzen mit Hilfe von RegEx. Ohne sie muss mit den Platzhaltern $1 bis $n operieren, um bei der Ersetzung auf die Werte der Gruppen zurückzugreifen.

    Wollte man etwa im oben verwendeten Dateinamen die Positionen von Monat und Jahr vertauschen, dann würde man klassisch so vorgehen:

    "Rechnung-08-17.xls" -replace 'Rechnung-(\d\d)-(\d\d).xls', 'Rechnung-$2-$1'

    Hat man es mit mehreren Gruppen in einem komplexeren Ausdruck zu tun, dann ist das Abzählen des Indexes relativ umständlich und man muss im schlimmsten Fall alle nummerischen Variablen ändern, wenn eine neue Gruppe hinzukommt.

    Hier schaffen Named Groups Abhilfe:

    "Rechnung-08-17.xls" -replace 'Rechnung-(?<monat>\d\d)-(?<jahr>\d\d).xls','Rechnung-${jahr}-${monat}'

    Im Ersetzungs­ausdruck kann man sich mit ${monat} und ${jahr} auf die Gruppen beziehen und ihren Wert wieder­verwenden.

    Keine Kommentare