PowerShell i operator -contains

143

Rozważ następujący fragment:

"12-18" -Contains "-"

Można by pomyśleć, że to się ocenia true, ale tak nie jest. falseZamiast tego zostanie to ocenione . Nie jestem pewien, dlaczego tak się dzieje, ale tak się dzieje.

Aby tego uniknąć, możesz zamiast tego użyć tego:

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

Teraz wyrażenie zostanie ocenione jako prawda.

Dlaczego pierwszy fragment kodu zachowuje się w ten sposób? czy jest w tym coś wyjątkowego -, co nie pasuje do przyjemności -Contains? Dokumentacja nie wspomina nic na ten temat.

tnw
źródło

Odpowiedzi:

196

-ContainsOperator nie zrobić podciąg porównań i mecz musi być na pełnym ciągu i służy do przeszukiwania kolekcji.

Z dokumentacji, do której linkowałeś:

-Zawiera Opis: Operator przechowalni. Informuje, czy zbiór wartości odniesienia zawiera jedną wartość testową.

W podanym przykładzie pracujesz z kolekcją zawierającą tylko jeden element w postaci ciągu.

Jeśli przeczytasz dokumentację, do której utworzyłeś łącze, zobaczysz przykład demonstrujący takie zachowanie:

Przykłady:

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

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

Myślę, że chcesz -Matchoperatora:

"12-18" -Match "-"

Który powraca True.

Ważne: Jak wskazano w komentarzach i dołączonej dokumentacji , należy zauważyć, że -Matchoperator używa wyrażeń regularnych do dopasowywania tekstu.

Kev
źródło
14
Dla kompletności, podczas gdy -Match może być dobrym dopasowaniem, używa wyrażenia regularnego. Jeśli ktoś chce, aby jednoznaczny ciąg znaków zawierał czek, należy zrobić tak, jak opisuje OP:"12-18".Contains("-")
8DH
4
@ 8DH - bardzo dobry chwyt :). Po ponownym przeczytaniu pytania, myślę, że muszę wyjaśnić różnicę między Containsoperatorem PowerShell a metodą .Contains() .NET String .
Kev
1
Jak już wspomniano w komentarzu powyżej, -Matchużywa wyrażenia regularnego. Oznacza to, że parametr ciągu jest wyrażeniem regularnym, a nie zwykłym ciągiem. Na przykład "hello" -Match "."zwróci wartość true, ponieważ "."jest wyrażeniem regularnym, w którym „.” będzie pasować do dowolnego znaku. Aby sprawdzić, czy ciąg zawiera kropkę: "hello" -Match "\."(zwraca false)
malla
1
@malla - słuszna uwaga, zredagowałem w notatce na ten temat. Dzięki.
Kev
To z pewnością „fałszywy przyjaciel”! :) Istnienie „-contains” oznacza „należący do listy”.
Raúl Salinas-Monteagudo
38

-Containsjest w rzeczywistości operatorem kolekcji. Prawdą jest, że kolekcja zawiera obiekt. Nie ogranicza się do strun.

-matchi-imatch są dopasowującymi łańcuchami wyrażeń regularnych i ustawiają zmienne automatyczne do użycia z przechwytywaniami.

-like, -ilikesą odpowiednikami podobnymi do SQL.

Eris
źródło
13

Możesz użyć like:

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

Lub splitza contains:

"12-18" -split "" -contains "-"
Esperento57
źródło