C# Regex: Como Expressões Regulares Funcionam em C#, Com Exemplos
NOTA: Eu originalmente escrevi esse post para o blog da empresa Stackify. Você pode ler o artigo original, em inglês, no site deles.
A manipulação de texto é uma das tarefas mais comuns na programação, sendo que praticamente todas as principais linguagens de programação oferecem suporte a regex (expressão regular) por meio de suas bibliotecas padrão. O C# não é exceção, portanto, hoje trazemos a você um guia de regex do C#.
Você aprenderá o que são expressões regulares, por que você deseja usá-las e como começar de uma maneira abrangente e acessível. Dessa forma, você poderá começar a usar expressões regulares para resolver problemas reais o mais rápido possível.
Prepare-se para sua jornada de aprendizado de regex, que começa agora!
O Que é Regex?
Uma expressão regular (também chamadas de regex, abreviação para regular expression) é uma expressão que contém um ou vários caracteres que expressam um determinado padrão no texto. Se isso parecer um pouco vago, um exemplo vai ajudar. Considere uma data no seguinte formato:
28-JUL-2023
Usando um regex, podemos expressar esse formato da seguinte forma:
[0-9]{2}-[A-Z]{3}-[0-9]{4}
Observe que a expressão regular acima expressa um padrão com:
- dois dígitos numéricos seguidos de um hífen
- três letras maiúsculas seguidas de um hífen
- mais quatro números
Você saberá mais sobre o significado de cada parte de uma regex em um minuto. Por enquanto, lembre-se de que a regex acima não sabe nada sobre datas. Acontece que conseguimos criar uma expressão regular que corresponde ao padrão ou ao formato da data. Todos os itens a seguir correspondem a essa regex, mesmo que não sejam datas válidas:
32-ABC-7894
30-FEV-1978
00-AAA-9999
Existe Regex no C#?
Sim, é claro. Mas isso não vem da própria linguagem. Em vez disso, o suporte a regex vem da .NET’s BCL (Base Class Library), que é essencialmente a biblioteca padrão do C#.
Por Que Usar Regex em C#?
Como você viu, regex é algo a ser usado para expressar um padrão que pode corresponder a um determinado texto.
Na prática, todos os usos de regex em C# ou em outras linguagens se resumem a três motivos: validação, manipulação e extração.
Validação
Um caso de uso incrivelmente comum para regex é a validação de dados. Por exemplo, digamos que você tenha um formulário da Web e queira garantir que um determinado campo só aceite entradas em um formato específico. Como resolver isso? O Regex vem em seu socorro.
Manipulação
Às vezes, você precisa alterar informações dentro do texto. Vamos voltar ao exemplo anterior. Imagine que, por motivos de compliance, você precise remover todos os números de telefone desse corpo de texto e substituí-los pela palavra “REDACTED”. Novamente, as expressões regulares seriam perfeitas para essa situação.
É interessante notar que as linguagens de programação não são as únicas a usar expressões regulares para resolver problemas. Até mesmo os editores de texto, como o Notepad++, oferecem recursos de localizar e substituir com o auxílio de expressões regulares.
Extração
Digamos que você tenha uma quantidade considerável de texto. Esse texto contém números de telefone que você precisa extrair. Você conhece o formato desses números e o fato de que eles estão dentro do texto, mas esse é o limite do seu conhecimento.
Como você faria para extrair essas informações? Um regex C# bem feito certamente seria útil nessa situação.
Como usar o Regex em C#: Primeiros passos na prática
O C# é uma linguagem orientada a objetos, portanto, não é de surpreender que você use uma classe para trabalhar com regex no C#. Mais especificamente, a classe de que estou falando é apropriadamente chamada de Regex
e reside no namespace System.Text.RegularExpressions
.
C# Regex: Um exemplo de validação
Vamos começar com um exemplo simples de validação sobre como usar regex para validar se várias cadeias de caracteres correspondem a um determinado padrão. A primeira etapa é adicionar a seguinte instrução using ao seu código:
Agora, vamos criar um array de strings e preenchê-la com alguns valores:
Por fim, percorreremos os valores e usaremos o método estático IsMatch
da classe Regex
para verificar qual das cadeias de caracteres corresponde ao padrão desejado:
Antes de prosseguir, vamos detalhar o padrão parte por parte:
- [0-9]{2}: A primeira parte significa “Corresponde exatamente a dois caracteres, que devem ser dígitos de 0 a 9”.
- -: Esse caractere corresponde exatamente a um hífen.
- [A-Z]{3}: Aqui, a expressão diz: “Vamos corresponder exatamente a três caracteres, que podem ser qualquer uma das letras de A a Z.”
- -: Isso corresponde a outro hífen
- [0-9]{4}: Isso já deve ser fácil de entender, certo? Exatamente quatro números.
Agora, vamos executar o código e ver o que obtemos:
A string '28-JUL-2023' corresponde ao padrão '[0-9]{2}-[A-Z]{3}-[0-9]{4}'
A string '89-ABC-1234' corresponde ao padrão '[0-9]{2}-[A-Z]{3}-[0-9]{4}'
A cadeia de caracteres '11-JUN-2022' corresponde ao padrão '[0-9]{2}-[A-Z]{3}-[0-9]{4}'
A cadeia de caracteres '11-JUN-2022, a date plus other stuff' corresponde ao padrão '[0-9]{2}-[A-Z]{3}-[0-9]{4}'
Os três primeiros resultados provavelmente não o surpreenderam. Eu até incluí algo que não é uma data, mas que corresponde ao padrão que estamos usando para realmente enfatizar que as expressões regulares tratam de padrões e formas e não de qualquer semântica dos dados que estamos procurando.
Entretanto, o quarto resultado pode tê-lo surpreendido. O texto de fato começa com dados que correspondem ao padrão que estamos procurando, mas depois tem algum texto adicional. E mesmo assim, essa string correspondeu!
A explicação para esse comportamento é simples e está explicada para nós no summary do método IsMatch
:
Indica se a expressão regular especificada encontra uma correspondência na cadeia de caracteres de entrada especificada.
A expressão regular de fato encontrou uma correspondência na string de entrada especificada (“11-JUN-2022, a date plus other stuff”), e é por isso que foi considerada uma correspondência.
Mas e se quiséssemos uma correspondência exata? Nesse caso, seria necessário alterar o padrão, adicionando um acento circunflexo (“^”) ao início do padrão e um cifrão (“$”) ao seu final. Em outras palavras, veja como o padrão deve ficar agora:
Se executarmos o código agora, ele exibirá apenas as cadeias de caracteres que são uma correspondência exata com o padrão:
A string '28-JUL-2023' corresponde ao padrão '^[0-9]{2}-[A-Z]{3}-[0-9]{4}
C# Regex: Um exemplo de manipulação
Considere que você tem um texto que contém dados sensíveis do usuário. Devido a questões de privacidade/compliance, você deseja excluir esses dados. Felizmente para você, é muito fácil usar uma regex para isso.
Vamos começar criando uma matriz contendo nomes e números de telefone de pessoas fictícias:
Em seguida, vamos criar o padrão para corresponder aos números de telefone:
O padrão acima é um pouco mais complexo do que os que usamos anteriormente, mas ainda é simples. No entanto, há alguns elementos novos:
- A barra invertida (\): Precisamos dela aqui para escapar dos parênteses de abertura e fechamento, que é um caractere com significado em uma expressão regular. Nesse caso, queremos de fato corresponder a um caractere “(“, portanto, precisamos escapar dele.
- O caractere \s: corresponde a um único espaço.
Por fim, vamos percorrer essa matriz e, para cada item, usar o método Regex.Replace
para gerar uma nova string na qual o número de telefone é substituído por todos os zeros:
Usar o método estático Replace
é fácil. Embora ele tenha várias sobrecargas, a que usamos recebe apenas três argumentos:
- a string de entrada
- o padrão que você deseja corresponder
- a string de substituição
Depois de executar o código, eis o resultado que obtemos:
Emily Johnson,(000) 000-0000
Benjamin Williams,(000) 000-0000
Olivia Davis,(000) 000-0000
Alexander Smith,(000) 000-0000
Sophia Brown,(000) 000-0000
William Anderson,(000) 000-0000
Ava Martinez,(000) 000-0000
James Thompson,(000) 000-0000
Isabella Wilson,(000) 000-0000
Michael Taylor,(000) 000-0000
C# Regex: Um exemplo de extração
Para o nosso último exemplo, vamos extrair dados de uma string usando uma expressão regular. Vamos começar convertendo o array do exemplo anterior em uma única string:
Em seguida, definimos o padrão novamente (o mesmo) e usamos o método estático Matches
para obter todas as correspondências da string:
A classe MatchCollection
contém todas as cadeias de caracteres que corresponderam ao padrão que fornecemos ao método. Esse objeto é enumerável, portanto, podemos fazer um loop sobre ele com um foreach:
E, finalmente, nossos resultados:
C# Regex: Uma Ferramenta Indispensável
Como dissemos na introdução, a manipulação de texto é um elemento básico da programação, e as expressões regulares facilitam essa tarefa. Neste guia de regex em C#, você aprendeu o que são expressões regulares, seus cenários de uso mais comuns e como começar a usar expressões regulares em C#.
Antes de ir embora, algumas dicas:
- Faça mais experimentos com a classe
Regex
. Ela oferece muitos recursos, e os métodos que usamos hoje têm muitas sobrecargas com recursos úteis. - Saiba mais e pratique a escrita de expressões regulares. Aqui está um ótimo site que você pode usar.
- Informe-se sobre as considerações de desempenho do C# regex. Por exemplo, leia este artigo da Microsoft sobre a compilação e a reutilização de expressões regulares.
Por fim, se quiser saber mais sobre o C# em geral, o blog da Stackify está repleto de recursos úteis. Como sugestão, dê uma olhada em os prós e contras dos 3 principais frameworks de teste de unidade para C#, como capturar exceções e localizar erros de aplicativos em C# e como funciona a reflexão em C#.
Obrigado pela leitura!
Encontrou algum erro no post? Sugira uma edição ← Git Criar Branch: 4 Maneiras Diferentes [Tradução] Tudo o que você precisa saber sobre configuração e gerenciamento de segredos em .NET →