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 912345678

Operadores 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]  # $true

Boas 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

Exercícios

  1. Escreva um script que use -match para 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"
    }
  2. Dada uma lista de processos (simule com uma array de nomes: "powershell", "notepad", "explorer"), use -contains para 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"
    }
  3. Use -replace para 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 $dataFormatada
  4. Verifique se a variável $x = 3.14 é do tipo [double] usando -is. Em seguida, tente converter a string "42" para [int] usando -as e 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"
    }
  5. 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"
    }