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:
- Curinga
*→ corresponde a quaisquer caracteres - Expressões regulares → uma versão mais poderosa dos curingas
(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 ⭐)
#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;
}
Saída:
Valid phone number
Invalid phone number
Resultado da execução:
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 ⭐⭐)
#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 ⭐⭐)
#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:
After hiding:138****5678
4. Busca Iterativa
(1) 4.1 regex_iterator
Exemplo: Encontrar todos os endereços de email (Dificuldade ⭐⭐⭐)
#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:
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 ⭐⭐)
#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:
Year: 2026
Month: 06
Day: 28
6. Casos de Uso Comuns
(1) 6.1 Validação de Entrada
| Cenário | Expressão Regular |
|---|---|
[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 ⭐⭐⭐)
#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 ⭐)
#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;
}
Saída:
-> 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 flagstd::regex_constants::optimize
P: E se houver muitos caracteres de escape? R: Use raw string literals (C++11):
// 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
-
Básico (Dificuldade ⭐): Use
std::regexpara verificar se uma string corresponde ao padrão "apenas dígitos" (^\d+$), testando "123", "12a3", "abc". -
Intermediário (Dificuldade ⭐⭐): Use
regex_searchpara extrair todos os endereços de email de um texto (correspondendo ao padrão\w+@\w+\.\w+). -
Desafio (Dificuldade ⭐⭐⭐): Use
regex_replacepara implementar uma função de "filtro de palavras sensíveis" — substituindo palavras sensíveis especificadas no texto por***. Suporte múltiplas palavras sensíveis.
- Expressões regulares: strings de correspondência de padrões
- std::regex constrói objetos regex
- std::regex_match para correspondência completa
- std::regex_search para correspondência de busca
- std::regex_replace substitui conteúdo correspondido
Próxima aula: Noções Básicas de Multithreading (#43)