Galera! Hoje vamos conversar, já que para falar de expressões regulares temos que ter um cuidado especial, se hoje vai ser seu primeiro contato com esse recurso e eu não tiver esse cuidado, posso fazer com que você nunca mais se interesse por esse assunto, e se já teve um contato e quer se aprofundar mais eu não quero deixar você decepcionado, por isso vamos conversar sobre o assunto e viajar neste mundo de “ninjas”.

Primeiro vamos às terminologias, o termo “expressão regular” é um pouco extensa, então a partir de agora vamos nos referir como ER. Um termo que você pode achar estranho é o “casar” (match) que neste caso não quer dizer juntar em laços matrimoniais com outra pessoa e sim a ação de bater, conferir, combinar, igualar, encontrar, encaixar e equiparar. E para completar essa seção temos o “padrão” (pattern) que é o objetivo que queremos alcançar ao escrever uma ER, casar um padrão esse padrão pode ser uma palavra, frase, linha, ou seja, o que quer que precise ser casado com nossa ER.

Para que servem as ERs?  Para dizer algo abrangente, quando definido seu padrão você tem uma lista finita ou não de possibilidade de casamento, por exemplo, a ER “[crv]aio” que pode casar com “caio”, ”raio”e “vaio” essa lista abrange especificamente essas três palavras somente.

Podemos utilizar ER para validar o formato do valor informado pelo usuário em um determinado campo, por exemplo, data, CPF, CEP, telefone, numero IP e tudo que você quiser verificar se está no formado que sua ER espera.

Podemos também procurar uma palavra especifica em um texto, trocar essa palavra por outra (replace com ER), podemos colocar agrupamentos na nossa ER e capturar esse agrupamento.

Para utilizarmos o recurso de ER em C# devemos fazer o uso do namespace System.Text.RegularExpressions.

Vamos ver um exemplo básico do básico:

Regex ER = new Regex("n[ãa]o", RegexOptions.None);

String[] texto = new String[10];

texto[0] = "Eu não quero";

texto[1] = "nao quero mais";

texto[2] = "Quero sim";

texto[3] = "O anao está lá";

texto[4] = "No ano de 1987";

texto[5] = "minimercado";

texto[6] = "mini-mercado";

texto[7] = "super-mercado";

texto[8] = "hiper-mercado";

texto[9] = "hiper mercado";

 

for (int i = 0; i < texto.Length; i++)

{

    string Casou = "casou";

    if (!ER.IsMatch(texto[i]))

        Casou = "não casou";

 

    Console.WriteLine(string.Format("O texto \"{0,-30}\" [{1}]", texto[i], Casou));

}

Entendendo o que isso faz:

1º) Declaramos nossa ER, a classe Regex que esta dentro do namespace System.Text.RegularExpression é o nosso cara responsável pelas operações de ER, na hora que instanciamos o objeto ER passamos nosso padrão(pattern) e nosso RegexOptions que neste caso é None, nosso padrão simplesmente diz que procuramos algo que tenha “n” seguido de “ã” ou “a” seguido de “o”, sendo assim poderemos ter “não”, “nao”, “anão”, “anao”, “naozinho” e por ai em diante.

2º) Criamos um array de string para servirem de repositório das nossas frases, e criamos algumas frases para nosso exemplo;

3º) Percorremos pelo nosso array de frases e testamos se a frase casa ou não casa com o padrão da ER em questão e logo em seguida imprimimos a frase e se ela casa ou não casa.

Muito básico e fácil não acharam? Criamos um objeto do tipo Regex, definimos o padrão que ele procurará, utilizamos o método IsMatch que retorna true ou false para o teste de casamento e exibimos para o usuário se casou ou não.

Reparem que para o casamento do exemplo a cima, que casou somente a frase que tinha “não” ou “nao” em seu conteúdo não importando sua localidade (começo, meio e fim).

Agora digamos que queremos casar somente a frase que contenha a palavra “não” ou “nao”, vamos mexer um pouco no padrão da nossa ER de forma a deixá-la mais específica.

Regex ER = new Regex(" n[ãa]o ", RegexOptions.None);

Apenas coloquei espaços atrás do “n” e na frente do “o”, deixando o seguinte padrão: Casar somente se espaço seguido de “n” seguido de “ã” ou “a” seguido de “o” seguido de espaço.

Com essa modificação somente a frase “Eu não quero” casou a frase “não quero mais” mesmo que tenha a palavra “não” não casou, pois obrigatoriamente deveria ter um espaço antes do “n” e a única frase que atende ao nosso padrão é a primeira, vamos ver outro exemplo e logo em seguida iremos melhorar essa nossa ER.

Vamos entender alguns operadores, caracteres curingas e outras mais.

Temos dois operadores importantes que é o “^” e “$”, esses representam respectivamente inicio e fim de uma linha, então podemos escrever um padrão que case uma linha inteira e não somente uma palavra ou parte dela, como pode casar uma frase que inicia ou termina com determinada palavra ou caractere.

Vamos para mais um exemplo.

Regex ER = new Regex(@"^quero", RegexOptions.None);

Esse padrão vai casar com frases que iniciam com “quero” observando nossas frases aparentemente temos uma que inicia com “Quero” a pergunta é? Vai casar?

Resposta simples, não, passamos o RegexOptions como None e por padrão o casamento é “case sensitive” (sensível ao tamanho), mas podemos proceder de duas formas:

1ª) Caso não a sensibilidade do tamanho não importar em nenhuma parte do nosso padrão podemos passar como parâmetro o RegexOptions. IgnoreCase no ligar do RegexOptions.None ficando:

                Regex ER = new Regex(@"^quero", RegexOptions.IgnoreCase);

2ª) Caso a sensibilidade do tamanho importar para o restante do padrão podemos alterar o padrão para que no primeiro caractere aceite “q” ou “Q” como fizemos no primeiro exemplo onde podíamos ter “a” ou “ã”, ficando:

                Regex ER = new Regex(@"^[qQ]uero", RegexOptions.None);

Essa analise você deve fazer sempre antes de iniciar um padrão para ER, pois quando você passa IgnoreCase coisas como “qUEro” vai ser tratado igual a “quero” e “Quero” e qualquer variação casando tudo, então é melhor criar um conjunto de caractere do que ignorar a sensibilidade.

Vamos entender melhor essa coisa de conjuntos, quando queremos dar a possibilidade de em um determinado ponto do padrão, poderem ter uma variação de combinações como nos exemplos acima onde tínhamos [qQ] e [ãa], para definir um conjunto, basta colocar as opções entre colchetes.

Vamos ver exemplos:

Regex ER = new Regex(@"[an][naã][ao]", RegexOptions.None);

Este casa com: ana, ano, aaa, aao, aãa, aão, nna, nno, naa,não,nãa e não.

Ou seja: A primeira letra pode ser “a” ou “n” a segunda pode ser “n”, “a” ou “ã” e a terceira pode ser “a” ou “o”.

Regex ER = new Regex(@"(mini|(su|hi)per)?mercado", RegexOptions.None);

Aqui temos uma novidade, o caractere “|” significa “ou” em um grupo, grupo por sua vez é tudo que esta cercado por parênteses, neste exemplo podemos casar com a seguinte regras: parte ou que começa com “mini” ou “su” e ou “hi” seguido de “per” e seguido ou não de qualquer caractere (“?” responsável por isso”) seguido de “mercado”.

Entendendo parte a parte: Temos dois momentos de “ou” e um dentro do outro, ou será “mini” ou será “su” seguido de “per” ou “hi” seguido de “per”, no primeiro momento ele define se fica com o “mini” ou com o segundo momento de ou onde ele define se “su” ou se “hi” ambos deveram ser seguidos de “per”, poderíamos ter escrito de uma forma mais direta que ficaria “(mini|super|hiper)?mercado” desta forma o “per” repete entre as opções, assim ficando “mini” ou “super” ou “hiper” seguido ou não de qualquer caractere seguido de “mercado”.

Eu tinha dito que iríamos resolver o problema com o “ n[ãa]o “ que não estava casando com a frase iniciada em “não “, bom vou utilizar de um recurso que verifica (IF) se a posição inicial é seguida de “n” ou de espaço seguida de “n”. Vamos ver como fica e depois eu explico melhor.

Regex ER = new Regex(@"(\s|^)n[ãa]o\s", RegexOptions.None);

Utilizamos o que vimos até agora para melhorar nossa ER onde criamos um grupo no inicio que pode ser um espaço ou inicio da linha seguido por “n” seguido por “ã” ou “a” seguido por “o” seguido por espaço.

Você pode ter observado que eu não utilizei um conjunto para “\s” e “^” ([\s^]n[ãa]o\s) o motivo é simples, o caractere “^” dentro de um conjunto não significa inicio de linha e sim nega o conjunto, então temos que utilizar um grupo e o operador “|” (ou).

Você já deve ter percebido que temos varias formas de escrever um padrão, a forma correta é aquela que vai atender a sua necessidade.

Por hoje nosso papo fica por aqui, voltaremos a falar mais sobre ER.

Até a próxima, ahh não se esqueçam de fazer o download do exemplo.