Pular para o conteúdo principal

Regex

Expressões regulares (regex) são ferramentas poderosas para correspondência de padrões e manipulação de texto. Veja como diferentes linguagens lidam com operações de regex.

Correspondência Básica de Padrões​

// Create regex
const pattern = /hello/i; // literal with flag
const pattern2 = new RegExp("hello", "i"); // constructor

// Test match
pattern.test("Hello World"); // true

// Find match
"Hello World".match(/hello/i); // ["Hello"]
"Hello World".search(/hello/i); // 0 (index)

// Find all matches
"hello hello".match(/hello/g); // ["hello", "hello"]

Operações de Substituição​

// Replace first match
"Hello World".replace(/hello/i, "Hi"); // "Hi World"

// Replace all matches
"hello hello".replace(/hello/g, "Hi"); // "Hi Hi"

// Replace with function
"hello world".replace(/\w+/g, (match) => match.toUpperCase()); // "HELLO WORLD"

Grupos de Captura​

// Capture groups
const match = "John Doe".match(/(w+) (w+)/);
// match[0] = "John Doe"
// match[1] = "John"
// match[2] = "Doe"

// Named groups (ES2018+)
const named = /(?<first>w+) (?<last>w+)/.exec("John Doe");
named.groups.first; // "John"
named.groups.last; // "Doe"

// Use in replace
"John Doe".replace(/(w+) (w+)/, "$2, $1"); // "Doe, John"

Padrões Comuns​

// Email
/^[\w\.-]+@[\w\.-]+\.[a-z]{2,}$/i

// Phone (US)
/^\+?1?[-. ]?\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})$/

// URL
/https?:\/\/(www\.)?[-a-zA-Z0-9@:%._\+~#=]{1,256}\.[a-zA-Z0-9()]{1,6}\b([-a-zA-Z0-9()@:%_\+.~#?&//=]*)/

// Digits only
/^\d+$/

// Alphanumeric
/^[a-zA-Z0-9]+$/

Principais Conclusões​

  • Suporte nativo vs biblioteca — JavaScript (/pattern/ ou new RegExp), Python (módulo re), Ruby (/pattern/), Java (Pattern/Matcher), C# (Regex), C++ (<regex>) e Go (regexp) incluem regex na biblioteca padrão. C requer POSIX regex.h ou uma biblioteca como PCRE; Zig não tem regex nativo e geralmente usa bibliotecas externas; Rust precisa do crate regex. Se você está construindo um projeto que usa fortemente correspondência de padrões, prefira uma linguagem com suporte nativo; para trabalho em sistemas ou embarcados, considere as dependências de bibliotecas.

  • Variações de sintaxe — A maioria das linguagens usa padrões estilo PCRE. JavaScript e Ruby permitem sintaxe literal: /hello/i para case-insensitive. Go e Rust usam padrões baseados em string: Regex::new(r"(?i)hello") em Rust ou regexp.Compile("(?i)hello") em Go. Operações de substituição também diferem: "hello hello".gsub(/hello/, "Hi") do Ruby vs. re.sub(r"hello", "Hi", text) do Python. Ao portar regex entre linguagens, fique atento às diferenças de escape — especialmente em literais de string onde barras invertidas podem precisar ser duplicadas.

  • Grupos de captura — Grupos nomeados (?<first>\w+) (?<last>\w+) são suportados em JavaScript, PHP, Rust, Python, C#, Java e Ruby, oferecendo acesso limpo como match.groups.first ou caps["first"]. O regex POSIX do C fornece regmatch_t para grupos posicionais, mas não grupos nomeados; o NSRegularExpression do Swift expõe ranges por índice, exigindo extração manual. Para analisar texto estruturado (ex.: linhas de log, arquivos de configuração), prefira uma linguagem com suporte a grupos nomeados para manter o código legível.

  • Ergonomia da API — Ruby e JavaScript oferecem a sintaxe mais concisa: "Hello World" =~ /hello/i retorna o índice de correspondência; "hello hello".gsub(/hello/, "Hi") faz substituição total em uma linha. C, C++ e Swift exigem mais código repetitivo: abrir arquivos, iterar com sregex_iterator, converter NSRange para índices de String. Para processamento rápido de texto e scripts, escolha Ruby, Python ou JavaScript; para código crítico em performance ou de baixo nível, aceite a verbosidade de C/C++ ou as APIs explícitas de Rust e Go.