Operadores avançados
Esta aula explora operadores avançados do PowerShell, como -match para expressões regulares, -contains e -in para verificação de coleções, -replace para substituição de padrões e operadores de tipo (-is, -as) para verificação e conversão de tipos. Inclui exemplos práticos e exercícios com respostas.
Nesta aula, vamos nos aprofundar em operadores que ampliam a capacidade de manipulação de strings, coleções e tipos no PowerShell. Esses operadores são essenciais para escrever scripts mais concisos e eficientes, permitindo desde validação de padrões até conversão segura de tipos.
Dominar esses operadores é fundamental para automatizar tarefas administrativas e processar dados de forma inteligente. Vamos abordar cada um com exemplos práticos que mostram seu uso no dia a dia.
-match (regex)
O operador -match utiliza expressões regulares (regex) para verificar se uma string corresponde a um padrão. Ele retorna $true se houver correspondência e automaticamente preenche a variável automática $matches com o resultado.
Expressões regulares são padrões de busca poderosos. Por exemplo, para verificar se um endereço de IP é válido, podemos usar "192.168.1.1" -match '^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$'. O operador é case-insensitive por padrão; para tornar case-sensitive, use -cmatch.
# Exemplo básico
$texto = "O PowerShell é poderoso"
if ($texto -match "power") {
Write-Host "Encontrado!"
Write-Host $matches[0] # Exibe "power"
}
# Capturando grupos
$data = "2025-03-19"
$data -match '(\d{4})-(\d{2})-(\d{2})'
Write-Host "Ano: $($matches[1]), Mês: $($matches[2]), Dia: $($matches[3])"
# Validação de e-mail
$email = "usuario@exemplo.com"
$email -match '^[\w.-]+@[\w.-]+\.\w+$'
Write-Host "E-mail válido? $($?)"-contains e -in
O operador -contains verifica se uma coleção contém um valor específico. Ele retorna $true se o valor estiver presente. Já -in faz o oposto: verifica se um valor está em uma coleção. Ambos são mais eficientes que o operador -eq em loops.
Importante: -contains verifica a existência exata do objeto na coleção, não suporta curingas. Para listas grandes, é mais rápido que .Contains() do .NET. Exemplo:
$frutas = @("maçã", "banana", "laranja")
# -contains
if ($frutas -contains "banana") {
Write-Host "Tem banana!"
}
# -in
if ("laranja" -in $frutas) {
Write-Host "Laranja está na lista"
}
# Comparação com -eq (menos eficiente)
$encontrado = $false
foreach ($fruta in $frutas) {
if ($fruta -eq "banana") { $encontrado = $true; break }
}-replace
O operador -replace substitui padrões em strings usando expressões regulares. Sintaxe: "string" -replace "padrão", "substituição". Se a substituição for omitida, o padrão é removido. Pode-se usar referências a grupos de captura com $1, $2, etc.
Exemplos práticos incluem sanitização de entradas, formatação de números e transformação de dados. O operador não modifica a string original; retorna uma nova string.
# Substituição simples
$texto = "Olá, mundo!"
$novo = $texto -replace "mundo", "PowerShell"
Write-Host $novo # Olá, PowerShell!
# Usando regex para remover espaços extras
$sujo = " texto com espaços "
$limpo = $sujo -replace '\s+', ' '
Write-Host "[$limpo]" # [texto com espaços]
# Substituição com grupos
$telefone = "(11) 91234-5678"
$formatado = $telefone -replace '\((\d{2})\)\s(\d{4,5})-(\d{4})', '$1 $2$3'
Write-Host $formatado # 11 912345678Operadores de tipo (-is, -as)
O operador -is verifica se um objeto é de um determinado tipo (ou subtipo), retornando $true ou $false. Já -as tenta converter o objeto para o tipo especificado; se falhar, retorna $null (sem erro).
Esses operadores são úteis para validação de parâmetros e conversão segura. Por exemplo, ao receber entrada do usuário, podemos verificar se é um número antes de processar.
# -is
$numero = 42
if ($numero -is [int]) {
Write-Host "É inteiro"
}
$data = Get-Date
if ($data -is [DateTime]) {
Write-Host "É data"
}
# -as
$entrada = "123"
$convertido = $entrada -as [int]
if ($convertido -ne $null) {
Write-Host "Valor numérico: $convertido"
} else {
Write-Host "Conversão falhou"
}
# Falha na conversão
$invalido = "abc" -as [int]
Write-Host $invalido # (nada, $null)
# Uso com tipos personalizados
class Pessoa {
[string]$Nome
}
$p = [Pessoa]@{Nome="João"}
$p -is [Pessoa] # $trueBoas práticas e observações finais
Ao usar -match, lembre-se de que a variável $matches é sobrescrita a cada operação. Para preservar resultados, copie para outra variável. Com -replace, tenha cuidado com caracteres especiais na substituição (use $$ para literal $). Os operadores -contains e -in são case-insensitive por padrão; use -ccontains e -cin para sensibilidade a maiúsculas.
Evite usar -is para verificar tipos em parâmetros de funções; prefira atributos de validação. -as é excelente para conversões seguras, mas lembre-se de testar o resultado contra $null.
Referências
- about_Comparison_Operators (Microsoft)
- about_Regular_Expressions (Microsoft)
- about_Operators (Microsoft)
- Regex101 - Testador de expressões regulares
- Everything about arrays (PowerShell)
- about_Type_Operators (Microsoft)
Exercícios
Escreva um script que use
-matchpara verificar se a string "PowerShell 7.4" contém um número de versão (padrão: dígito(s).dígito(s)). Exiba o que foi encontrado.✓ Resposta:$texto = "PowerShell 7.4" if ($texto -match '\d+\.\d+') { Write-Host "Versão encontrada: $($matches[0])" } else { Write-Host "Nenhuma versão encontrada" }Dada uma lista de processos (simule com uma array de nomes: "powershell", "notepad", "explorer"), use
-containspara verificar se "notepad" está na lista e exiba uma mensagem.✓ Resposta:$processos = @("powershell", "notepad", "explorer") if ($processos -contains "notepad") { Write-Host "O processo notepad está na lista" } else { Write-Host "notepad não está na lista" }Use
-replacepara transformar a string "2025-03-19" no formato "19/03/2025" (dia/mês/ano).✓ Resposta:$data = "2025-03-19" $dataFormatada = $data -replace '(\d{4})-(\d{2})-(\d{2})', '$3/$2/$1' Write-Host $dataFormatadaVerifique se a variável
$x = 3.14é do tipo [double] usando-is. Em seguida, tente converter a string "42" para [int] usando-ase exiba o resultado.✓ Resposta:$x = 3.14 if ($x -is [double]) { Write-Host "x é double" } $numero = "42" -as [int] if ($numero -ne $null) { Write-Host "Convertido: $numero" } else { Write-Host "Falha na conversão" }Crie um script que receba uma string do usuário (use
Read-Host) e, usando-match, verifique se é um endereço IP válido (formato xxx.xxx.xxx.xxx, com cada octeto entre 0 e 255). Dica: a regex deve validar cada octeto, mas para simplificar, use^\d{1,3}\.\d{1,3}\.\d{1,3}\.\d{1,3}$e depois verifique se cada octeto está na faixa.✓ Resposta:$ip = Read-Host "Digite um endereço IP" if ($ip -match '^(\d{1,3})\.(\d{1,3})\.(\d{1,3})\.(\d{1,3})$') { $valido = $true for ($i = 1; $i -le 4; $i++) { $octeto = [int]$matches[$i] if ($octeto -lt 0 -or $octeto -gt 255) { $valido = $false break } } if ($valido) { Write-Host "IP válido" } else { Write-Host "IP inválido: octeto fora do intervalo" } } else { Write-Host "Formato inválido" }