PowerShell e o operador -contains

143

Considere o seguinte trecho:

"12-18" -Contains "-"

Você acha que isso é avaliado true, mas não é. Isso será avaliado em falsevez disso. Não sei por que isso acontece, mas acontece.

Para evitar isso, você pode usar isso:

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

Agora a expressão será avaliada como verdadeira.

Por que o primeiro trecho de código se comporta dessa maneira? há algo de especial -nisso que não se encaixa bem -Contains? A documentação não menciona nada sobre isso.

tnw
fonte

Respostas:

196

O -Containsoperador não faz comparações de substring e a correspondência deve estar em uma sequência completa e é usada para pesquisar coleções.

Na documentação à qual você vinculou:

-Contém Descrição: Operador de contenção. Informa se uma coleção de valores de referência inclui um único valor de teste.

No exemplo que você forneceu, está trabalhando com uma coleção que contém apenas um item de sequência.

Se você ler a documentação à qual vinculou, verá um exemplo que demonstra esse comportamento:

Exemplos:

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

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

Eu acho que o que você quer é o -Matchoperador:

"12-18" -Match "-"

O que retorna True.

Importante: Conforme indicado nos comentários e na documentação vinculada , deve-se observar que o -Matchoperador usa expressões regulares para executar a correspondência de texto.

Kev
fonte
14
Para ser completo, enquanto -Match pode ser uma boa correspondência, ele usa regex. Se alguém quiser que uma string não ambígua contenha, verifique o que o OP descreve:"12-18".Contains("-")
8DH 30/11
4
@ 8DH - captura muito boa :). Depois de reler a pergunta, acho que preciso esclarecer a diferença entre o Containsoperador do PowerShell e o método .Contains() .NET String .
Kev
1
Como já mencionado no comentário acima, -Matchusa regex. Isso significa que o parâmetro string é uma regex, não uma string normal. Por exemplo, "hello" -Match "."retornará true, porque "."é uma regex em que um '.' irá corresponder a qualquer caractere. Para verificar se uma string contém um ponto final: "hello" -Match "\."(retorna false)
malla
1
@malla - bom ponto, eu editei uma nota sobre isso. Obrigado.
Kev
Este é certamente um "falso amigo"! :) A existência de "-contains" significa "pertencente a uma lista".
Raúl Salinas-Monteagudo
38

-Containsé realmente um operador de coleção. É verdade se a coleção contém o objeto. Não é limitado a strings.

-matche-imatch são correspondentes de cadeia de expressão regular e defina variáveis ​​automáticas para usar com capturas.

-like, -ilikesão correspondentes do tipo SQL.

Eris
fonte
13

Você pode usar like:

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

Ou splitpara contains:

"12-18" -split "" -contains "-"
Esperento57
fonte