Referência de Expressões Regulares
Uma referência abrangente para expressões regulares JavaScript/TypeScript - sintaxe, flags, métodos e padrões do mundo real comumente usados em aplicativos React.
Busque em todas as páginas da documentação
Uma referência abrangente para expressões regulares JavaScript/TypeScript - sintaxe, flags, métodos e padrões do mundo real comumente usados em aplicativos React.
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥
| Método | Retorna | Descrição |
|---|---|---|
regex.test(str) | boolean | Retorna true se o padrão corresponder em qualquer lugar da string |
regex.exec(str) | RegExpExecArray | null | Retorna detalhes da correspondência (grupos, índice) ou null |
str.match(regex) | RegExpMatchArray | null | Retorna correspondências - o comportamento muda com a flag g |
str.matchAll(regex) | IterableIterator<RegExpMatchArray> | Retorna um iterador de todas as correspondências (requer flag g) |
str.search(regex) | number | Retorna o índice da primeira correspondência ou -1 |
str.replace(regex, replacement) | string | Substitui a primeira correspondência (ou todas com a flag g) |
str.replaceAll(regex, replacement) | string | Substitui todas as correspondências (requer flag g) |
str.split(regex) | string[] | Divide a string por correspondências de regex |
Referência rápida - as operações de regex mais comuns em TypeScript.
// Testa se uma string corresponde
const isEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/.test("user@example.com"); // true
// Extrai correspondências
const matches = "2024-01-15".match(/(\d{4})-(\d{2})-(\d{2})/);
// matches[1] = "2024", matches[2] = "01", matches[3] = "15"
// Grupos de captura nomeados
const result = "2024-01-15".match(/(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/);
// result?.groups?.year = "2024"
// Substitui com padrão
const slug = "Hello World! Foo".replace(/[^a-zA-Z0-9]+/g, "-").toLowerCase();
// "hello-world-foo"
// Divide por padrão
const words = "one, two; three".split(/[,;]\s*/);
// ["one", "two", "three"]Quando usar isso: Validação de entrada, análise de texto, roteamento de URL, lógica de pesquisa/filtro e transformação de dados em formulários e utilitários.
"use client";
import { useState } from "react";
interface ValidationResult {
field: string;
value: string;
isValid: boolean;
message: string;
}
const VALIDATORS: Record<string, { pattern: RegExp; message: string }> = {
email: {
pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/,
message: "Deve ser um endereço de e-mail válido",
},
phone: {
pattern: /^\+?[\d\s\-()]{7,15}$/,
message: "Deve ser um número de telefone válido (7-15 dígitos)",
},
url: {
pattern: /^https?:\/\/[^\s/$.?#].[^\s]*$/i,
message: "Deve ser uma URL válida começando com http(s)://",
},
zipCode: {
pattern: /^\d{5}(-\d{4})?$/,
message: "Deve ser um CEP dos EUA válido (12345 ou 12345-6789)",
},
password: {
pattern: /^(?=.*[a-z])(?=.*[A-Z])(?=.*\d)(?=.*[!@#$%^&*]).{8,}$/,
message: "Mínimo 8 caracteres, 1 maiúscula, 1 minúscula, 1 dígito, 1 caractere especial",
},
};
export default function RegexValidationDemo() {
const [results, setResults] = useState<ValidationResult[]>([]);
const [input, setInput] = useState("");
const [selected, setSelected] = useState("email");
function validate() {
const { pattern, message } = VALIDATORS[selected];
const isValid = pattern.test(input);
setResults((prev) => [
{ field: selected, value: input, isValid, message: isValid ? "Válido" : message },
...prev,
]);
}
return (
<div className="space-y-4 p-4 max-w-md">
<select
value={selected}
onChange={(e) => setSelected(e.target.value)}
className="border rounded px-2 py-1 w-full"
>
{Object.keys(VALIDATORS).map((key) => (
<option key={key} value={key}>{key}</option>
))}
</select>
<input
type="text"
value={input}
onChange={(e) => setInput(e.target.value)}
placeholder={`Digite ${selected}...`}
className="border rounded px-2 py-1 w-full"
/>
<button onClick={validate} className="bg-blue-600 text-white px-4 py-1 rounded">
Validar
</button>
<ul className="space-y-1 text-sm">
{results.map((r, i) => (
<li key={i} className={r.isValid ? "text-green-600" : "text-red-600"}>
<strong>{r.field}:</strong> "{r.value}" - {r.message}
</li>
))}
</ul>
</div>
);
}O que isso demonstra:
RegExp.test() para validação booleana// Predefinidas
/\d/ // Dígito [0-9]
/\D/ // Não dígito [^0-9]
/\w/ // Caractere de palavra [a-zA-Z0-9_]
/\W/ // Caractere não de palavra
/\s/ // Espaço em branco (espaço, tab, nova linha)
/\S/ // Não espaço em branco
/./ // Qualquer caractere exceto nova linha
// Personalizadas
/[abc]/ // Qualquer um de a, b ou c
/[a-z]/ // Intervalo: a até z
/[^abc]/ // NÃO a, b ou c (negação)
/[a-zA-Z]/ // Qualquer letra
/[0-9]/ // Igual a \d/a*/ // 0 ou mais
/a+/ // 1 ou mais
/a?/ // 0 ou 1
/a{3}/ // Exatamente 3
/a{2,5}/ // 2 a 5
/a{2,}/ // 2 ou mais
// Guloso vs. Preguiçoso
/".+"/ // Guloso: corresponde a "foo" e "bar" como uma correspondência em: "foo" and "bar"
/".+?"/ // Preguiçoso: corresponde a "foo" e depois "bar" separadamente/^hello/ // Começa com "hello"
/world$/ // Termina com "world"
/\bhello\b/ // Palavra inteira "hello" (limite de palavra)
/\Bhello/ // NÃO em um limite de palavra// Grupo de captura
/(foo|bar)/ // Corresponde a "foo" ou "bar", captura-o
/(\d{3})-(\d{4})/ // Captura código de área e número separadamente
// Grupo sem captura
/(?:foo|bar)/ // Agrupa sem capturar
// Grupo de captura nomeado
/(?<area>\d{3})-(?<number>\d{4})/
// Retrovisor
/(\w+)\s+\1/ // Corresponde a palavras repetidas: "the the"// Lookahead positivo: corresponde a "foo" seguido por "bar"
/foo(?=bar)/ // "foobar" ✓ "foobaz" ✗
// Lookahead negativo: corresponde a "foo" NÃO seguido por "bar"
/foo(?!bar)/ // "foobaz" ✓ "foobar" ✗
// Lookbehind positivo: corresponde a "bar" precedido por "foo"
/(?<=foo)bar/ // "foobar" ✓ "bazbar" ✗
// Lookbehind negativo: corresponde a "bar" NÃO precedido por "foo"
/(?<!foo)bar/ // "bazbar" ✓ "foobar" ✗/pattern/g // Global - encontra todas as correspondências, não apenas a primeira
/pattern/i // Case-insensitive (ignora maiúsculas/minúsculas)
/pattern/m // Multiline - ^ e $ correspondem ao início/fim de linha
/pattern/s // Dotall - . corresponde a novas linhas também
/pattern/u // Unicode - suporte Unicode adequado
/pattern/d // Índices - inclui índices de início/fim nos resultados
/pattern/v // Conjuntos Unicode (ES2024) - operações de conjunto em classes de caracteres
// Combina flags
/pattern/gi // Global + case-insensitivetest() - Verificação Booleanaconst emailRegex = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
emailRegex.test("user@site.com"); // true
emailRegex.test("not-an-email"); // false
// AVISO: test() com a flag /g é stateful
const re = /a/g;
re.test("abc"); // true (lastIndex = 1)
re.test("abc"); // false (lastIndex = 0, resetado)
re.test("abc"); // true (ciclo se repete)exec() - Informações Detalhadas da Correspondênciaconst dateRegex = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
const result = dateRegex.exec("Date: 2024-03-15");
if (result) {
result[0]; // "2024-03-15" (correspondência completa)
result[1]; // "2024" (grupo 1)
result.index; // 6 (posição na string)
result.groups?.year; // "2024"
result.groups?.month; // "03"
result.groups?.day; // "15"
}match() - Método de String// Sem /g: igual a exec()
"Price: $42.50".match(/\$(\d+\.\d{2})/);
// ["$42.50", "42.50", index: 7, groups: undefined]
// Com /g: retorna um array de todas as correspondências (sem grupos)
"cat bat hat".match(/[a-z]at/g);
// ["cat", "bat", "hat"]matchAll() - Iterar Todas as Correspondências com Gruposconst text = "Jan 15, Feb 20, Mar 5";
const regex = /(?<month>[A-Z][a-z]+)\s+(?<day>\d+)/g;
for (const match of text.matchAll(regex)) {
console.log(`${match.groups?.month} ${match.groups?.day}`);
}
// "Jan 15"
// "Feb 20"
// "Mar 5"
// Ou converter para array
const allMatches = [...text.matchAll(regex)];replace() e replaceAll()// Substituição simples
"hello world".replace(/world/, "TypeScript"); // "hello TypeScript"
// Substituição global
"aabbcc".replace(/b/g, "X"); // "aaXXcc"
// Com grupos de captura ($1, $2, etc.)
"John Smith".replace(/(\w+)\s(\w+)/, "$2, $1"); // "Smith, John"
// Com grupos nomeados
"2024-01-15".replace(
/(?<y>\d{4})-(?<m>\d{2})-(?<d>\d{2})/,
"$<m>/$<d>/$<y>"
); // "01/15/2024"
// Com uma função
"hello world".replace(/\b\w/g, (char) => char.toUpperCase());
// "Hello World"
// Substituição complexa com função
"img_001.png, img_002.jpg".replace(
/img_(\d+)\.(png|jpg)/g,
(_match, num, ext) => `photo-${parseInt(num)}.${ext}`
);
// "photo-1.png, photo-2.jpg"split() - Dividir por Padrão// Dividir por múltiplos delimitadores
"one, two; three four".split(/[,;\s]+/);
// ["one", "two", "three", "four"]
// Dividir mantendo o delimitador (grupo de captura)
"one+two-three".split(/([+-])/);
// ["one", "+", "two", "-", "three"]
// Limitar resultados
"a-b-c-d-e".split(/-/, 3);
// ["a", "b", "c"]Variação 1: Validação de E-mail
// Validação básica de e-mail
const basicEmail = /^[^\s@]+@[^\s@]+\.[^\s@]+$/;
// E-mail mais rigoroso (padrão comum do mundo real)
const stricterEmail = /^[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}$/;
basicEmail.test("user@example.com"); // true
basicEmail.test("user@sub.domain.co.uk"); // true
basicEmail.test("user@.com"); // falseVariação 2: Análise de URL
const urlRegex = /^(?<protocol>https?):\/\/(?<host>[^/:]+)(?::(?<port>\d+))?(?<path>\/[^?#]*)?(?:\?(?<query>[^#]*))?(?:#(?<fragment>.*))?$/;
const parsed = urlRegex.exec("https://example.com:8080/api/users?page=2#top");
if (parsed?.groups) {
parsed.groups.protocol; // "https"
parsed.groups.host; // "example.com"
parsed.groups.port; // "8080"
parsed.groups.path; // "/api/users"
parsed.groups.query; // "page=2"
parsed.groups.fragment; // "top"
}Variação 3: Verificador de Força de Senha
function checkPasswordStrength(password: string): string[] {
const checks = [
{ regex: /.{8,}/, label: "Pelo menos 8 caracteres" },
{ regex: /[a-z]/, label: "Letra minúscula" },
{ regex: /[A-Z]/, label: "Letra maiúscula" },
{ regex: /\d/, label: "Um dígito" },
{ regex: /[!@#$%^&*()_+\-=[\]{};':"\\|,.<>/?]/, label: "Caractere especial" },
{ regex: /^(?!.*(.)\1{2})/, label: "Sem 3+ caracteres repetidos" },
];
return checks.filter((c) => !c.regex.test(password)).map((c) => c.label);
}
checkPasswordStrength("weak"); // ["Pelo menos 8 caracteres", "Letra maiúscula", "Um dígito", "Caractere especial"]
checkPasswordStrength("Str0ng!Pass"); // []Variação 4: Gerador de Slug
function toSlug(text: string): string {
return text
.toLowerCase()
.trim()
.replace(/[^\w\s-]/g, "") // Remove caracteres não de palavra (exceto espaços e hífens)
.replace(/[\s_]+/g, "-") // Substitui espaços/sublinhados por hífens
.replace(/-+/g, "-") // Colapsa múltiplos hífens
.replace(/^-|-$/g, ""); // Remove hífens iniciais/finais
}
toSlug("Hello, World! This is a Test"); // "hello-world-this-is-a-test"
toSlug(" --Foo & Bar-- "); // "foo--bar"Variação 5: Extrair Números de Texto
function extractNumbers(text: string): number[] {
return [...text.matchAll(/-?\d+\.?\d*/g)].map((m) => parseFloat(m[0]));
}
extractNumbers("Price: $42.50, Qty: 3, Discount: -5.25");
// [42.5, 3, -5.25]Variação 6: Interpolação de String de Modelo
function interpolate(template: string, vars: Record<string, string>): string {
return template.replace(/\{\{(\w+)\}\}/g, (_match, key: string) => vars[key] ?? `{{${key}}}`);
}
interpolate("Hello {{name}}, welcome to {{place}}!", {
name: "Alice",
place: "Wonderland",
});
// "Hello Alice, welcome to Wonderland!"Variação 7: Destacar Correspondências de Pesquisa (React)
function highlightMatches(text: string, query: string): (string | JSX.Element)[] {
if (!query.trim()) return [text];
const escaped = query.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
const regex = new RegExp(`(${escaped})`, "gi");
const parts = text.split(regex);
return parts.map((part, i) =>
regex.test(part) ? <mark key={i} className="bg-yellow-200">{part}</mark> : part
);
}
// Uso: <p>{highlightMatches("Hello World", "world")}</p>
// Renderiza: Hello <mark>World</mark>Variação 8: Sanitizar Entidades HTML
function stripHtmlTags(html: string): string {
return html.replace(/<[^>]*>/g, "");
}
stripHtmlTags("<p>Hello <strong>world</strong></p>"); // "Hello world"
function escapeRegex(str: string): string {
return str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
}
escapeRegex("Price: $10.00 (USD)"); // "Price: \\$10\\.00 \\(USD\\)"Variação 9: Analisar Linha CSV
function parseCSVLine(line: string): string[] {
const result: string[] = [];
const regex = /(?:^|,)("(?:[^"]|"")*"|[^,]*)/g;
let match: RegExpExecArray | null;
while ((match = regex.exec(line)) !== null) {
let value = match[1];
if (value.startsWith('"') && value.endsWith('"')) {
value = value.slice(1, -1).replace(/""/g, '"');
}
result.push(value);
}
return result;
}
parseCSVLine('Alice,30,"New York, NY","She said ""hi"""');
// ["Alice", "30", "New York, NY", 'She said "hi"']Variação 10: Formatador de Número de Telefone
function formatPhone(raw: string): string {
const digits = raw.replace(/\D/g, "");
const match = digits.match(/^(\d{1,3})?(\d{3})(\d{3})(\d{4})$/);
if (!match) return raw;
const [, country, area, prefix, line] = match;
return country ? `+${country} (${area}) ${prefix}-${line}` : `(${area}) ${prefix}-${line}`;
}
formatPhone("12125551234"); // "+1 (212) 555-1234"
formatPhone("2125551234"); // "(212) 555-1234"Variação 11: Detecção de Cartão de Crédito
const CARD_PATTERNS: Record<string, RegExp> = {
visa: /^4\d{12}(?:\d{3})?$/,
mastercard: /^5[1-5]\d{14}$/,
amex: /^3[47]\d{13}$/,
discover: /^6(?:011|5\d{2})\d{12}$/,
};
function detectCardType(number: string): string | null {
const cleaned = number.replace(/\D/g, "");
for (const [type, pattern] of Object.entries(CARD_PATTERNS)) {
if (pattern.test(cleaned)) return type;
}
return null;
}
detectCardType("4111 1111 1111 1111"); // "visa"
detectCardType("5500 0000 0000 0004"); // "mastercard"Variação 12: Extrair Hashtags e Menções
function extractHashtags(text: string): string[] {
return [...text.matchAll(/#(\w+)/g)].map((m) => m[1]);
}
function extractMentions(text: string): string[] {
return [...text.matchAll(/@(\w+)/g)].map((m) => m[1]);
}
const tweet = "Hey @alice and @bob, check out #TypeScript #React!";
extractHashtags(tweet); // ["TypeScript", "React"]
extractMentions(tweet); // ["alice", "bob"]Variação 13: Validação de Endereço IP
const ipv4Regex = /^(?:(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)\.){3}(?:25[0-5]|2[0-4]\d|1\d\d|[1-9]?\d)$/;
ipv4Regex.test("192.168.1.1"); // true
ipv4Regex.test("256.1.1.1"); // false
ipv4Regex.test("10.0.0.255"); // trueVariação 14: Extrator de Links Markdown
function extractMarkdownLinks(md: string): Array<{ text: string; url: string }> {
return [...md.matchAll(/\[([^\]]+)\]\(([^)]+)\)/g)].map((m) => ({
text: m[1],
url: m[2],
}));
}
extractMarkdownLinks("Visit [Google](https://google.com) or [GitHub](https://github.com)");
// [{ text: "Google", url: "https://google.com" }, { text: "GitHub", url: "https://github.com" }]Variação 15: Conversão Camel Case / Snake Case
function camelToSnake(str: string): string {
return str.replace(/[A-Z]/g, (letter) => `_${letter.toLowerCase()}`);
}
function snakeToCamel(str: string): string {
return str.replace(/_([a-z])/g, (_match, letter: string) => letter.toUpperCase());
}
camelToSnake("backgroundColor"); // "background_color"
snakeToCamel("background_color"); // "backgroundColor"
function toKebabCase(str: string): string {
return str
.replace(/([a-z])([A-Z])/g, "$1-$2")
.replace(/[\s_]+/g, "-")
.toLowerCase();
}
toKebabCase("backgroundColor"); // "background-color"
toKebabCase("Hello World"); // "hello-world"// Tipo RegExp
const pattern: RegExp = /\d+/g;
// RegExpMatchArray - retornado por String.match() / RegExp.exec()
const result: RegExpMatchArray | null = "abc123".match(/(\d+)/);
if (result) {
const full: string = result[0];
const group: string = result[1];
const idx: number = result.index ?? 0;
}
// RegExpExecArray com grupos nomeados
const dateMatch = /(?<year>\d{4})-(?<month>\d{2})/.exec("2024-03");
if (dateMatch?.groups) {
// groups é Record<string, string> - requer encadeamento opcional
const year: string | undefined = dateMatch.groups.year;
}
// Mapa de validador com tipo seguro
interface Validator {
pattern: RegExp;
message: string;
}
const validators: Record<string, Validator> = {
email: { pattern: /^[^\s@]+@[^\s@]+\.[^\s@]+$/, message: "E-mail inválido" },
};
// Tipo de literal de template com validação regex (apenas em tempo de compilação)
type HexColor = `#${string}`;
function setColor(color: HexColor) { /* ... */ }
setColor("#ff0000"); // OK
// setColor("red"); // Erro de tipotest() com a flag /g é stateful - O objeto regex rastreia lastIndex. Chamar test() repetidamente em strings diferentes produz resultados inesperados. Correção: Omita a flag g ao usar test(), ou crie um novo regex a cada vez.
Esquecer de escapar caracteres especiais - Caracteres como ., *, +, ?, (, ), [, {, $, ^, |, \ têm significado especial. Correção: Use um helper: str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&") para escapar a entrada do usuário antes de construir um regex.
Correspondência gulosa captura demais - /".+"/.exec('"foo" and "bar"') corresponde a "foo" and "bar" como uma única correspondência. Correção: Use o quantificador preguiçoso ".+?" para corresponder à menor string possível.
match() com /g descarta grupos de captura - Com a flag global, match() retorna apenas correspondências completas, não grupos. Correção: Use matchAll() em vez disso quando precisar de informações de grupo com correspondência global.
Backtracking catastrófico - Padrões como /(a+)+$/ em strings longas que não correspondem podem travar o navegador. Correção: Evite quantificadores aninhados nos mesmos caracteres. Use padrões atômicos ou teste com verificadores de ReDoS.
\b não funciona com Unicode - Limites de palavra usam a definição ASCII de "caractere de palavra" ([a-zA-Z0-9_]). Caracteres acentuados como é são tratados como não-palavra. Correção: Use a flag /u e limites explícitos ao trabalhar com texto internacional.
Novas linhas não correspondem a . - Por padrão, . corresponde a qualquer caractere exceto \n. Correção: Use a flag /s (dotall) para fazer . corresponder a caracteres de nova linha, ou use [\s\S] como uma alternativa universal.
Esquecer as âncoras ^ e $ na validação - /\d+/.test("abc123xyz") retorna true porque encontra dígitos em qualquer lugar. Correção: Use ^ e $ para impor a correspondência de string inteira: /^\d+$/.
replace() substitui apenas a primeira correspondência - Sem a flag g, apenas a primeira ocorrência é substituída. Correção: Sempre use a flag /g ou replaceAll() quando quiser substituir todas as ocorrências.
Construir regex a partir da entrada do usuário sem escapar - Se um usuário digitar (hello) em uma caixa de pesquisa e você usar new RegExp(input), isso criará um grupo de captura em vez de corresponder a parênteses literais. Correção: Sempre escape a entrada do usuário antes de passá-la para new RegExp().
| Alternativa | Use Quando | Não Use Quando |
|---|---|---|
String.includes() | Verificação simples de substring sem correspondência de padrão | Você precisa de curingas ou lógica de padrão |
String.startsWith() / endsWith() | Verificando prefixo ou sufixo | O prefixo ou sufixo varia por padrão |
Zod .regex() | Validação de esquema em formulários com zod | Você precisa extrair ou transformar conteúdo correspondido |
| API URL / URLSearchParams | Análise de URLs | Correspondência de padrões arbitrários semelhantes a URL em texto |
Intl.NumberFormat | Formatação de números para exibição | Extração de números de texto misto |
Bibliotecas de parser (ex: date-fns) | Análise complexa de data/hora | Correspondência de formato de data simples |
test() é um método RegExp que retorna um booleano - use-o quando você só precisa saber se um padrão correspondematch() é um método String que retorna os detalhes da correspondência (correspondência completa, grupos, índice) ou nulltest() é mais rápido quando você não precisa de detalhes da correspondência/g - test() atualiza lastIndex no objeto regexexec() retorna uma correspondência por vez - chame-o em um loop com um regex /g para iterarmatchAll() retorna um iterador de todas as correspondências de uma vez - mais limpo e menos propenso a errosmatchAll() requer a flag /g; exec() funciona com ou sem elamatchAll() em código moderno - evita a armadilha stateful de lastIndex dos loops exec()new RegExp(userInput)input.replace(/[.*+?^${}()|[\]\\]/g, "\\$&")new RegExp() - isso pode causar erros de sintaxe ou ataques ReDoSString.includes() para correspondência simples de substring em vez disso(?<name>pattern) - atribui um nome a um grupo de capturamatch.groups.name em vez de posicional match[1](a+)+ que criam caminhos de correspondência exponenciais(x+)+, (x+)*, (x*)* no mesmo conjunto de caracteres(?=...) e lookbehinds (?<=...) são de largura zero - eles afirmam uma condição sem consumir caracteres(...) consomem o texto correspondido e o incluem no resultado(?=...) para corresponder a "seguido por" sem incluir o texto seguinte(?!...) para corresponder a "NÃO seguido por"a++), grupos atômicos ((?>...)) ou alguma sintaxe PCRE/s (dotall) e /d (índices) foram adicionadas em ES2018/ES2022 - ambientes mais antigos podem não suportá-lasnew RegExp("\\d") você precisa de barras invertidas duplasRegExp.exec() e String.match() retornam RegExpMatchArray | null - sempre verifique nullRecord<string, string> na propriedade groups - use encadeamento opcionalmatchAll(), o tipo de retorno é IterableIterator<RegExpMatchArray>/u habilita a correspondência completa de Unicode - sem ela, o regex trata pares substitutos como dois caracteres\p{...} como \p{Letter} ou \p{Emoji}/u ao trabalhar com texto internacional para evitar bugs sutis de correspondência de caracteres/^[^\s@]+@[^\s@]+\.[^\s@]+$/ pega a maioria dos erros de digitação e é bom para a experiência do usuário.email() que lidam com casos de borda comuns^ e $ correspondem ao início/fim de toda a string/m (multiline) para fazer ^ e $ corresponderem ao início/fim de cada linha/s (dotall) para fazer . corresponder a caracteres de nova linha[\s\S] em vez de . para corresponder a qualquer caractere, incluindo novas linhas, sem a flag /sreplace() sem /g substitui apenas a primeira correspondênciareplace() com /g substitui todas as correspondênciasreplaceAll() sempre substitui todas as correspondências - requer a flag /g se um regex for passadoreplaceAll() com um argumento de string substitui todas as ocorrências sem precisar de regexreplaceAll() foi adicionado em ES2021 - use replace(/pattern/g, ...) para ambientes mais antigosRevisado por Chris St. John·Última atualização: 10 de jul. de 2026
🤖 Read the SystemsArchitect.io Blog for over 100+ cloud architecture articles 🔥