PowerShell und der Operator -contains

142

Betrachten Sie das folgende Snippet:

"12-18" -Contains "-"

Sie würden denken, dass dies bewertet wird true, aber es tut nicht. Dies wird falsestattdessen ausgewertet . Ich bin mir nicht sicher, warum das passiert, aber es tut es.

Um dies zu vermeiden, können Sie stattdessen Folgendes verwenden:

"12-18".Contains("-")

Jetzt wird der Ausdruck als wahr ausgewertet.

Warum verhält sich das erste Code-Snippet so? Gibt es etwas Besonderes, mit -dem man nicht gut spielt -Contains? In der Dokumentation wird nichts darüber erwähnt.

tnw
quelle

Antworten:

195

Der -ContainsOperator führt keine Teilzeichenfolgenvergleiche durch, und die Übereinstimmung muss sich auf einer vollständigen Zeichenfolge befinden und wird zum Durchsuchen von Sammlungen verwendet.

Aus der Dokumentation, die Sie verlinkt haben:

-Enthält Beschreibung: Containment-Operator. Gibt an, ob eine Sammlung von Referenzwerten einen einzelnen Testwert enthält.

In dem von Ihnen angegebenen Beispiel arbeiten Sie mit einer Sammlung, die nur ein Zeichenfolgenelement enthält.

Wenn Sie die Dokumentation lesen, auf die Sie verlinkt haben, sehen Sie ein Beispiel, das dieses Verhalten demonstriert:

Beispiele:

PS C:\> "abc", "def" -Contains "def"
True

PS C:\> "Windows", "PowerShell" -Contains "Shell"
False  #Not an exact match

Ich denke, was Sie wollen, ist der -MatchBetreiber:

"12-18" -Match "-"

Welches kehrt zurück True.

Wichtig: Wie in den Kommentaren und in der verknüpften Dokumentation ausgeführt , sollte beachtet werden, dass der -MatchOperator reguläre Ausdrücke verwendet , um einen Textabgleich durchzuführen.

Kev
quelle
14
Der Vollständigkeit halber verwendet -Match zwar eine gute Übereinstimmung, verwendet jedoch Regex. Wenn man möchte, dass eine eindeutige Zeichenfolge eine Prüfung enthält, sollte man wie im OP beschrieben "12-18".Contains("-")
vorgehen
4
@ 8DH - sehr guter Fang :). Nachdem ich die Frage erneut gelesen habe, denke ich, dass ich den Unterschied zwischen dem ContainsPowershell-Operator und der .Contains() .NET- String Methode klären muss .
Kev
1
Wie bereits im obigen Kommentar erwähnt, -Matchwird Regex verwendet. Das bedeutet, dass der Zeichenfolgenparameter ein regulärer Ausdruck ist, keine normale Zeichenfolge. Gibt beispielsweise "hello" -Match "."true zurück, da "."es sich um einen regulären Ausdruck handelt, in dem ein '.' passt zu jedem Zeichen. So überprüfen Sie, ob eine Zeichenfolge einen "hello" -Match "\."
Punkt
1
@alla - guter Punkt, ich habe in einem Hinweis dazu bearbeitet. Vielen Dank.
Kev
Dies ist sicherlich ein "falscher Freund"! :) Die Existenz von "-contains" bedeutet "Zugehörigkeit zu einer Liste".
Raúl Salinas-Monteagudo
38

-Containsist eigentlich ein Sammlungsbetreiber. Es ist wahr, wenn die Sammlung das Objekt enthält. Es ist nicht auf Zeichenfolgen beschränkt.

-matchund-imatch sind String-Matcher für reguläre Ausdrücke und legen automatische Variablen für die Verwendung mit Captures fest.

-like, -ilikeSind SQL-ähnliche Matcher.

Eris
quelle
13

Sie können verwenden like:

"12-18" -like "*-*"

Oder splitfür contains:

"12-18" -split "" -contains "-"
Esperento57
quelle