C++: Expressões Regulares

Última atualização: 2026-08-26

Na aula 41, aprendemos sobre operações com arquivos.

Agora, vamos aprender expressões regulares — o "canivete suíço" do processamento de texto.

Validar emails, extrair números de telefone, substituir texto... expressões regulares oferecem uma solução concisa para tudo isso.


1. Visão Geral de Expressões Regulares

(1) 1.1 O Que São Expressões Regulares?

Expressões regulares (Regex) são uma linguagem de descrição de padrões de texto usada para corresponder, buscar e substituir texto.

Analogia do mundo real:


(2) 1.2 Biblioteca de Expressões Regulares do C++

O C++11 introduziu suporte a expressões regulares no header regex.

Quatro funções principais:

Função Propósito
std::regex_match Correspondência completa
std::regex_search Busca
std::regex_replace Substituição
std::regex_iterator Busca iterativa


2. Correspondência Básica

(1) 2.1 regex_match — Correspondência Completa

Exemplo: Validando um número de telefone (Dificuldade ⭐)

▶ Exemplo 1: Aplicação de expressão regular (Dificuldade ⭐)

CPP
#include <iostream>
#include <regex>
#include <string>

int main() {
 std::string phone = "13812345678";
 std::regex pattern("^1[3-9]\\d{9}$"); // Regex de número de telefone
 
 if (std::regex_match(phone, pattern)) {
 std::cout << "Valid phone number" << std::endl;
 } else {
 std::cout << "Invalid phone number" << std::endl;
 }
 
 return 0;
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
Valid phone number
Invalid phone number

Resultado da execução:

TEXT 📖 Somente leitura
Valid phone number

(2) 2.2 Sintaxe de Expressões Regulares

Símbolo Significado Exemplo
. Qualquer caractere a.c corresponde a abc
^ Início ^abc corresponde a strings começando com abc
$ Fim abc$ corresponde a strings terminando com abc
* Zero ou mais a* corresponde a aaa
+ Um ou mais a+ corresponde a aaa
? Zero ou um a? corresponde a a ou ``
{n} Exatamente n vezes a{3} corresponde a aaa
[abc] Conjunto de caracteres [abc] corresponde a a ou b ou c
[^abc] Conjunto negado [^abc] corresponde a qualquer caractere exceto abc
\d Dígito \d corresponde a 0-9
\w Caractere de palavra \w corresponde a a-z, A-Z, 0-9, _


3. Busca e Substituição

(1) 3.1 regex_search — Busca

Exemplo: Encontrando um email (Dificuldade ⭐⭐)

CPP
#include <iostream>
### ▶ Exemplo 2: Aplicação de expressão regular (Dificuldade ⭐)

#include <regex>
#include <string>

int main() {
 std::string text = "Contact me:abc@example.com or test@gmail.com";
 std::regex pattern("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}");
 
 std::smatch match;
 if (std::regex_search(text, match, pattern)) {
 std::cout << "Found email: " << match[0] << std::endl;
 }
 
 return 0;
}

(2) 3.2 regex_replace — Substituição

Exemplo: Mascarando os quatro dígitos do meio de um número de telefone (Dificuldade ⭐⭐)

CPP
#include <iostream>
#include <regex>
#include <string>

int main() {
 std::string phone = "13812345678";
 std::regex pattern("(\\d{3})\\d{4}(\\d{4})");
 
 std::string result = std::regex_replace(phone, pattern, "$1****$2");
 std::cout << "After hiding:" << result << std::endl;
 
 return 0;
}

Resultado da execução:

TEXT 📖 Somente leitura
After hiding:138****5678


4. Busca Iterativa

(1) 4.1 regex_iterator

Exemplo: Encontrar todos os endereços de email (Dificuldade ⭐⭐⭐)

CPP
#include <iostream>
#include <regex>
#include <string>

int main() {
 std::string text = "Contact me:abc@example.com or test@gmail.com";
 std::regex pattern("[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\\.[a-zA-Z]{2,}");
 
 auto begin = std::sregex_iterator(text.begin(), text.end(), pattern);
 auto end = std::sregex_iterator();
 
 std::cout << "Found email: " << std::endl;
 for (auto it = begin; it != end; ++it) {
 std::cout << it->str() << std::endl;
 }
 
 return 0;
}

Resultado da execução:

TEXT 📖 Somente leitura
Found email: 
abc@example.com
test@gmail.com


5. Agrupamento e Captura

(1) 5.1 Agrupamento

Use parênteses () para criar grupos, que podem extrair substrings.

Exemplo: Extraindo uma data (Dificuldade ⭐⭐)

CPP
#include <iostream>
#include <regex>
#include <string>

int main() {
 std::string date = "2026-06-28";
 std::regex pattern("(\\d{4})-(\\d{2})-(\\d{2})");
 
 std::smatch match;
 if (std::regex_match(date, match, pattern)) {
 std::cout << "Year: " << match[1] << std::endl;
 std::cout << "Month: " << match[2] << std::endl;
 std::cout << "Day: " << match[3] << std::endl;
 }
 
 return 0;
}

Resultado da execução:

TEXT 📖 Somente leitura
Year: 2026
Month: 06
Day: 28


6. Casos de Uso Comuns

(1) 6.1 Validação de Entrada

Cenário Expressão Regular
Email [a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}
Número de telefone ^1[3-9]\d{9}$
Cartão de identidade ^\d{17}[\dXx]$
Endereço IP ^(\d{1,3}\.){3}\d{1,3}$

(2) 6.2 Extração de Informações

Exemplo: Extraindo links de HTML (Dificuldade ⭐⭐⭐)

CPP
#include <iostream>
#include <regex>
#include <string>

int main() {
 std::string html = "<a href=\"https://example.com\">Example</a>";
 std::regex pattern("<a href=\"([^\"]+)\"");
 
 std::smatch match;
 if (std::regex_search(html, match, pattern)) {
 std::cout << "Link: " << match[1] << std::endl;
 }
 
 return 0;
}

▶ Exemplo 3: Validando formato de email (Dificuldade ⭐)

CPP
#include <iostream>
#include <regex>
#include <string>

bool isValidEmail(const std::string& email) {
    std::regex pattern(R"([a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,})");
    return std::regex_match(email, pattern);
}

int main() {
    std::string emails[] = {"test@example.com", "invalid-email", "user.name@domain.org"};

    for (const auto& email : emails) {
        if (isValidEmail(email)) {
            std::cout << email << " -> Effective" << std::endl;
        } else {
            std::cout << email << " -> Invalid" << std::endl;
        }
    }

    return 0;
}
▶ Experimente

Saída:

TEXT 📖 Somente leitura
 -> Effective
 -> Invalid

❓ Perguntas Frequentes

P: E se as expressões regulares forem muito lentas? R: - Compile uma vez, use múltiplas vezes (o construtor std::regex é lento) - Use a flag std::regex_constants::optimize


P: E se houver muitos caracteres de escape? R: Use raw string literals (C++11):

CPP
// Difícil de ler
std::regex pattern("\\\\d+");

// Fácil de ler
std::regex pattern(R"(\d+)");

P: Expressões regulares podem lidar com todo o texto? R: Não. Analisar HTML/XML com regex é muito complexo — use um parser dedicado.


📖 Resumo

Ponto-Chave Resumo
regex_match Correspondência completa
regex_search Busca
regex_replace Substituição
regex_iterator Busca iterativa
Agrupamento Use () para extrair substrings

📝 Exercícios

  1. Básico (Dificuldade ⭐): Use std::regex para verificar se uma string corresponde ao padrão "apenas dígitos" (^\d+$), testando "123", "12a3", "abc".

  2. Intermediário (Dificuldade ⭐⭐): Use regex_search para extrair todos os endereços de email de um texto (correspondendo ao padrão \w+@\w+\.\w+).

  3. Desafio (Dificuldade ⭐⭐⭐): Use regex_replace para implementar uma função de "filtro de palavras sensíveis" — substituindo palavras sensíveis especificadas no texto por ***. Suporte múltiplas palavras sensíveis.



Próxima aula: Noções Básicas de Multithreading (#43)

Web-Tutorial.com

Equipe Técnica Web-Tutorial

Uma plataforma de tutoriais mantida por diversos desenvolvedores. Cada tutorial é escrito e revisado por profissionais da área correspondente. Trabalhamos para manter nosso conteúdo preciso e confiável — se encontrar algum problema, avise-nos.

100%