PowerShell y el operador -contains

143

Considere el siguiente fragmento:

"12-18" -Contains "-"

Uno pensaría que esto se evalúa true, pero no es así. Esto evaluará a en su falselugar. No estoy seguro de por qué sucede esto, pero lo hace.

Para evitar esto, puede usar esto en su lugar:

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

Ahora la expresión se evaluará como verdadera.

¿Por qué el primer fragmento de código se comporta así? ¿Hay algo especial en -eso con lo que no se juega bien -Contains? La documentación no menciona nada al respecto.

tnw
fuente

Respuestas:

197

El -Containsoperador no realiza comparaciones de subcadenas y la coincidencia debe estar en una cadena completa y se utiliza para buscar colecciones.

De la documentación que vinculó a:

-Contiene Descripción: Operador de contención. Indica si una colección de valores de referencia incluye un solo valor de prueba.

En el ejemplo que proporcionó, está trabajando con una colección que contiene solo un elemento de cadena.

Si lees la documentación que vinculaste, verás un ejemplo que demuestra este comportamiento:

Ejemplos:

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

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

Creo que lo que quieres es el -Matchoperador:

"12-18" -Match "-"

Que vuelve True.

Importante: Como se señaló en los comentarios y en la documentación vinculada , debe tenerse en cuenta que el -Matchoperador utiliza expresiones regulares para realizar la coincidencia de texto.

Kev
fuente
14
Para completar, mientras que -Match puede ser una buena combinación, usa expresiones regulares. Si se desea que una cadena inequívoca contenga, se debe hacer lo que el OP describe:"12-18".Contains("-")
8DH
44
@ 8DH - muy buena captura :). Después de releer la pregunta, creo que necesito aclarar la diferencia entre el Containsoperador de PowerShell y el método .Contains() .NET String .
Kev
1
Como ya se mencionó en el comentario anterior, -Matchutiliza expresiones regulares. Eso significa que el parámetro de cadena es una expresión regular, no una cadena normal. Por ejemplo, "hello" -Match "."devolverá verdadero, porque "."es una expresión regular donde un '.' coincidirá con cualquier personaje. Para verificar si una cadena contiene un punto final: "hello" -Match "\."(devuelve falso)
malla
1
@malla: buen punto, he editado una nota sobre esto. Gracias.
Kev
¡Este es ciertamente un "falso amigo"! :) La existencia de "-contains" que significa "perteneciente a una lista".
Raúl Salinas-Monteagudo
38

-Containses en realidad un operador de colección. Es cierto si la colección contiene el objeto. No se limita a las cuerdas.

-matchy-imatch coinciden con cadenas de expresiones regulares, y establecen variables automáticas para usar con capturas.

-like, -ilikeson comparadores de tipo SQL.

Eris
fuente
13

Puedes usar like:

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

O splitpara contains:

"12-18" -split "" -contains "-"
Esperento57
fuente