Oft möchte man prüfen, ob ein String eine bestimmte Zeichenkette enthält – am besten unabhängig von der Groß- und Kleinschreibung. Und wenn sich ein PowerShell-Neuling mit den Möglichkeiten befasst, stößt er schnell auf die vielen Vergleichsoperatoren, darunter contains
und auch viele andere, die mit einem i wie in case-insensitive beginnen. Es gibt sogar icontains
, also genau das, was wir suchen, nicht wahr?
Wie es nicht geht: -contains, -ccontains und -icontains
Zunächst einmal unterscheiden contains
und icontains
beide nicht zwischen Groß- und Kleinschreibung. Wer das möchte, greift stattdessen auf ccontains
mit c wie case-sensitive zurück.
Probieren wir beide aus:
"It's a trap!" -ccontains "trap"
"It's a trap!" -icontains "it"
Output:
False
False
Offensichtlich enthält das Beispiel sowohl „trap“ als auch ein großgeschriebenes „it“, und trotzdem findet PowerShell sie nicht. Der Grund dafür ist einfach: Die beiden Operatoren wirken nicht auf Strings, sondern auf Arrays – und da wir nur einen String angegeben haben, konvertiert PowerShell ihn implizit in einen Array und sucht nun in diesem Array, das aus einem einzigen Element besteht, erfolglos nach einem Element „trap“ beziehungsweise „it“ (groß- oder kleingeschrieben).
Klarer wird die Funktionsweise anhand folgender Beispielen:
"It's", "a", "trap", "!" -ccontains "trap"
"It's a trap!" -icontains "it's a trap!"
Output:
True
True
Im ersten Beispiel suchen wir tatsächlich in einem Array aus vier Elementen, und eines davon ist „trap“, darum ist der Vergleich wahr. Im zweiten Beispiel wird der String wieder in ein Array aus einem Element umgewandelt, aber der schreibungsunabhängige Vergleich ist trotzdem wahr, weil wir genau diesen String (unabhängig von Groß- und Kleinschreibung) suchen.
Jetzt wissen wir, wie diese Vergleichsoperatoren funktionieren – aber wir wissen auch, dass sie ungeeignet sind, einen Substring in einem String zu finden. Welche Möglichkeiten haben wir also dann?
Möglichkeit 1: Contains-Methode
Die gute Nachricht ist, dass Strings in PowerShell Objekte sind und eine eigene Methode namens Contains
mitbringen. Erfolg!
"It's a trap!".Contains("It")
Output:
True
Leider hält diese Methode sich aber strikt an Groß- und Kleinschreibung, weshalb Folgendes leider nicht wie gewünscht klappt:
"It's a trap!".Contains("it")
Output:
False
Möglichkeit 2: regulärer Ausdruck
Selbst viele erfahrene Programmierer scheuen vor regular expressions (RegEx) zurück, obwohl das sehr schade ist. In diesem Fall lösen sie das Problem sehr einfach und elegant, ohne kompliziert zu sein:
"It's a trap!" -imatch "it"
Output:
True
Das ist sogar der kürzeste Befehl auf dieser Seite. Hier wird der Vergleichsoperator imatch
(oder match
, aber ich bevorzuge die explizite Variante) mit dem Suchmuster „it“ eingesetzt.
Man könnte sogar mit einem einzigen Befehl prüfen, ob „it“ oder „trap“ beide in dem String enthalten sind:
"It's a trap!" -imatch "it|trap"
Output:
True