PowerShell dan operator -berisi

149

Pertimbangkan cuplikan berikut:

"12-18" -Contains "-"

Anda akan berpikir ini mengevaluasi true, tetapi ternyata tidak. Ini akan mengevaluasi menjadi false. Saya tidak yakin mengapa ini terjadi, tetapi itu terjadi.

Untuk menghindarinya, Anda dapat menggunakan ini sebagai gantinya:

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

Sekarang ekspresi akan dievaluasi menjadi benar.

Mengapa cuplikan kode pertama berperilaku seperti itu? apakah ada sesuatu yang istimewa tentang -hal itu yang tidak cocok -Contains? The dokumentasi tidak menyebutkan apa-apa tentang hal itu.

tnw
sumber

Jawaban:

209

The -Containsoperator tidak melakukan substring perbandingan dan pertandingan harus pada tali lengkap dan digunakan untuk koleksi pencarian.

Dari dokumentasi yang Anda tautkan ke:

-Berisi Deskripsi: Operator penahanan. Memberi tahu apakah kumpulan nilai referensi menyertakan satu nilai pengujian.

Dalam contoh yang Anda berikan, Anda bekerja dengan koleksi yang hanya berisi satu item string.

Jika Anda membaca dokumentasi yang Anda tautkan, Anda akan melihat contoh yang menunjukkan perilaku ini:

Contoh:

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

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

Saya pikir yang Anda inginkan adalah -Matchoperator:

"12-18" -Match "-"

Yang kembali True.

Penting: Seperti yang ditunjukkan dalam komentar dan dalam dokumentasi yang ditautkan , perlu diperhatikan bahwa -Matchoperator menggunakan ekspresi reguler untuk melakukan pencocokan teks.

Kev
sumber
14
Untuk kelengkapan, sementara -Match mungkin cocok, ini menggunakan regex. Jika seseorang ingin string yang tidak ambigu berisi centang yang harus dilakukan seperti yang dijelaskan OP:"12-18".Contains("-")
8DH
4
@ 8DH - tangkapan yang sangat bagus :). Setelah membaca ulang pertanyaan saya rasa saya perlu mengklarifikasi perbedaan antara Containsoperator PowerShell dan metode .Contains() NET String .
Kev
1
Seperti yang sudah disebutkan dalam komentar di atas, -Matchmenggunakan regex. Itu berarti parameter string adalah regex, bukan string normal. Misalnya, "hello" -Match "."akan mengembalikan true, karena "."merupakan regex dengan '.' akan cocok dengan karakter apapun. Untuk memeriksa apakah sebuah string berisi tanda titik: "hello" -Match "\."(mengembalikan false)
malla
1
Ini pasti "teman palsu"! :) Adanya "-mengandung" yang berarti "milik daftar".
Raúl Salinas-Monteagudo
39

-Containssebenarnya adalah operator koleksi. Memang benar jika koleksi berisi objek. Itu tidak terbatas pada string.

-matchdan-imatch merupakan pencocokan string ekspresi reguler, dan menyetel variabel otomatis untuk digunakan dengan tangkapan.

-like, -ilikeadalah pencocokan mirip SQL.

Eris
sumber
15

Anda dapat menggunakan like:

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

Atau splituntuk contains:

"12-18" -split "" -contains "-"
Esperento57
sumber