Expressões Regulares em Go com Exemplos
Expressões regulares (regex) são uma ferramenta poderosa para buscar, extrair e substituir texto com base em padrões. Na linguagem Go (Golang), o trabalho com expressões regulares é implementado através do pacote padrão regexp. Neste artigo, vamos detalhar como usar expressões regulares em Go: desde a busca simples até substituições complexas com grupos de captura.
1. Fundamentos do pacote regexp
O pacote regexp fornece duas abordagens principais: uso rápido e único (funções de nível de pacote) e trabalho performático com um padrão pré-compilado (estrutura Regexp). Para uso repetido, sempre compile o padrão antecipadamente.
Compilação de uma expressão regular
package main
import ( "fmt" "regexp")
func main() { // Compilação do padrão (forma recomendada com tratamento de erro) pattern, err := regexp.Compile(`\\d+`) if err != nil { fmt.Println("Erro de compilação:", err) return } // Para casos simples — sem tratamento de erro (pânico em padrão inválido) patternMust := regexp.MustCompile(`[a-z]+`) fmt.Println(pattern, patternMust)}Compile retorna um erro se o padrão for inválido. MustCompile causa pânico — use-o apenas para padrões estáticos.
2. Operações básicas: busca e verificação
Vamos examinar os principais métodos para verificar correspondências e buscar substrings.
Verificação de correspondência parcial
pattern := regexp.MustCompile(`go`)text := "Estou estudando Golang"
// MatchString — verifica se a string contém uma substring que corresponde ao padrãomatched := pattern.MatchString(text)fmt.Println(matched) // true (pois "go" está contido em "Golang")Verificação de correspondência total
// Para verificar se a string inteira corresponde ao padrão, use as âncoras ^ e $fullPattern := regexp.MustCompile(`^[a-zA-Z]+$`)fmt.Println(fullPattern.MatchString("Hello")) // truefmt.Println(fullPattern.MatchString("Hello1")) // falseBusca da primeira correspondência
datePattern := regexp.MustCompile(`\\d{2}\\.\\d{2}\\.\\d{4}`)text := "Hoje é 15.03.2024, e amanhã será 16.03.2024"
// FindString — retorna a primeira correspondênciafirstDate := datePattern.FindString(text)fmt.Println(firstDate) // "15.03.2024"Busca de todas as correspondências
// FindAllString — retorna um slice de todas as correspondênciasallDates := datePattern.FindAllString(text, -1) // -1 — todas as correspondênciasfmt.Println(allDates) // ["15.03.2024" "16.03.2024"]
// Limitação de quantidade: FindAllString(text, 1) — apenas a primeira3. Grupos de captura e substituições
Grupos de captura permitem extrair partes da correspondência. Em Go, os grupos são indicados por parênteses ().
Extração de dados por grupos
// Padrão para extrair nome e idade: "Nome: [nome], Idade: [número]"personPattern := regexp.MustCompile(`Nome: (\\w+), Idade: (\\d+)`)text := "Nome: Alex, Idade: 30"
// FindStringSubmatch — retorna um slice: [correspondência_total, grupo1, grupo2, ...]matches := personPattern.FindStringSubmatch(text)if len(matches) > 0 { fmt.Println("Correspondência total:", matches[0]) // "Nome: Alex, Idade: 30" fmt.Println("Nome:", matches[1]) // "Alex" fmt.Println("Idade:", matches[2]) // "30"}Grupos nomeados (Go 1.21+)
// A partir da versão Go 1.21, é possível usar grupos nomeados: (?P<nome>padrão)pattern := regexp.MustCompile(`(?P<name>\\w+)@(?P<domain>\\w+\\.\\w+)`)text := "test@example.com"
// SubexpNames — obtém os nomes dos gruposgroupNames := pattern.SubexpNames()matches := pattern.FindStringSubmatch(text)
// Cria um mapa: nome_do_grupo