VB .NET - Usando Expressões Regulares para localizar texto


Neste artigo vou mostrar como podemos usar expressões regulares para localizar texto em um projeto Windows Forms usando a linguagem VB .NET.

Eu já abordei um pouco da teoria sobre Expressões Regulares em artigos anteriores que podem ser consultados nas referências.

Este artigo é essencialmente prático e mostra como localizar uma string em um texto , contar ocorrências de um determinado critério e localizar duplicatas de um critério em um texto.

A classe Regex representa o mecanismo para tratar as expressões regulares na plataforma .NET . Ela pode ser usado para analisar rapidamente grandes quantidades de texto para encontrar padrões de caracteres específicos; para extrair, editar, substituir ou excluir substrings de texto, ou para adicionar as strings extraídas a uma coleção para gerar um relatório.

Para usar as expressões regulares, definimos o padrão desejado para identificar em um fluxo de texto usando a sintaxe documentada nos Elementos de linguagem das expressões regulares. A seguir instanciamos um objeto Regex. Finalmente, executamos alguma operação, como a substituição de texto que corresponda ao padrão de expressão regular, ou a identificação de um padrão coincidente.

Para realizar estas operações vou usar o método Regex.IsMatch que indica se a expressão regular encontra uma correspondência no texto desejado, o método Regex.Matches que procurar em um texto por todas as ocorrências de uma expressão regular e retorna as ocorrências.

Vou usar também a classe MatchCollection que representa o conjunto ou coleção de ocorrências bem sucedidas encontradas pela aplicação interativa de um expressão regular em um texto. A coleção é imutável (somente-leitura) contendo zero ou mais objetos Match.

Se a consulta for feita com sucesso a coleção será preenchida com um objeto Match para cada correspondência encontrada no texto. Se a consulta falhar a coleção não irá conter objetos Match e a propriedade Count será igual a zero.

Criando a solução WIndows Forms

Abra o Visual Studio 2012 Express for desktop e clique em New Project;

Selecione a linguagem Visual Basic e o template Windows Forms Application informando o nome VBNET_Regex1;

Inclua os seguintes controles a partir da Toolbox no formulário form1.vb;

Disponha os controles no formulário conforme o leiaute abaixo:

Na propriedade Texto do controle txtTexto eu inclui um pequeno texto de Fernando Pessoa sobre o qual iremos aplicar os conceitos das expressões regulares.

Uma das primeiras medidas que tomamos e verificar se foi fornecido um critério de busca no controle txtCriterio:

  If String.IsNullOrEmpty(txtCriterio.Text) Then
            MessageBox.Show("Informe o valor do critério para busca !", "Erro", MessageBoxButtons.OK, MessageBoxIcon.Information)
            txtCriterio.Focus()
            Return
 End If

1- Definindo o Case Sensitive

Usamos o checkbox chkCaseSensitive para ativar a opção IgnoreCase da enumeração RegexOptions:

A enumeração RegexOptions fornece valores enumerados para usar para definir opções de expressões regulares. Os valores possíveis são:

Valor Descrição
None Especifica que nenhuma opção foi definida
IgnoreCase Especifica a comparação case-sensitive
ExplicitCapture Especifica que as únicas capturas válidas são explicitamente nomeadas ou grupos numerados do formulário (? <name> ...).
Isso permite que os parênteses sem nome atuem como grupos de não captura, sem a deselegância sintática da expressão (:? ...).
Singleline Especifica modo linha-única. Muda o significado do ponto (.) Para que coincida com todos os caracteres (em vez de cada caractere, exceto \n).
IgnorePatternWhitespace Elimina espaços em branco sem escape do padrão e permite comentários marcados com #. No entanto, o valor IgnorePatternWhitespace não  afeta ou elimina o espaço em branco nas classes de caracteres.
ECMAScript Permite o comportamento compatível com ECMAScript para a expressão. Este valor pode ser usado apenas em conjunto com os valores IgnoreCase, Multiline, e Compiled. A utilização deste valor com quaisquer outros valores gera uma exceção.
CultureInvariant Especifica que as diferenças culturais na linguagem será ignorada.
Compiled Especifica que a expressão regular é compilada para um assembly. Isto obtém um rendimento melhor na execução, mas aumenta o tempo de inicialização. Este valor não deve ser atribuído à propriedade Opções ao chamar o método CompileToAssembly.
Multiline Modo multilinha. Altera o significado de ^ e $ para que eles correspondam ao início e final, respectivamente, de qualquer linha, e não apenas  o início e o fim de toda a cadeia.
RightToLeft Especifica que a pesquisa será da direita para a esquerda em vez de da esquerda para a direita.

Conforme a seleção do usuário ativamos a opção RegexOptions.IgnoreCase que ignora o case sensitive que é definido por padrão:

 If chkCaseSensitive.Checked And Not rdbLocalizarCriterio.Checked Then
       colecao = Regex.Matches(txtTexto.Text, txtCriterio.Text)
ElseIf Not chkCaseSensitive.Checked And Not rdbLocalizarCriterio.Checked Then
      colecao = Regex.Matches(txtTexto.Text, txtCriterio.Text, RegexOptions.IgnoreCase)
End If

A instrução Regex.Matches irá procurar um texto por todas as ocorrências de uma expressão regular e retorna as ocorrências na coleção.

2- Localizando o critério

 If rdbLocalizarCriterio.Checked Then
            lbResultado.Items.Add("")
            If Regex.IsMatch(txtTexto.Text, txtCriterio.Text) Then
                lbResultado.Items.Add("Critério encontrado")
            Else
                lbResultado.Items.Add("Critério  não encontrado.")
            End If
End If

O código usa Regex.IsMatch para verificar a existência do critério no texto. Quando a primeira ocorrência for encontrada é exibida a mensagem ao usuário.

3- Localizando palavras duplicadas no texto

 If rdbLocalizarDuplicatas.Checked Then
            lbResultado.Items.Add("")
            lbResultado.Items.Add("Existem duplicatas para o critério : ")
            lbResultado.Items.Add("-> " & txtCriterio.Text)
            lbResultado.Items.Add("-----------------------")

            For Each match As Match In colecao
                lbResultado.Items.Add(" posicao -> " & vbTab & match.Index)
            Next
End If

Percorrendo os objetos Match na coleção podemos identificar o índice - match.Index - do mesmo que indica a posição da ocorrência no texto.

4- Contando ocorrências de um critério em um texto

 If rdbContarOcorrencias.Checked Then
            lbResultado.Items.Add("")
            lbResultado.Items.Add("Existem " & colecao.Count & " ocorrências ")
            lbResultado.Items.Add("Para o critério -> " & txtCriterio.Text)
End If

A coleção MatchCollection - colecao - possui a propriedade Count que usamos para contar o número de ocorrências do padrão regex no texto.

Executando o projeto teremos o seguinte resultado:

Pegue o projeto completo aqui: VBNET_Regex1.zip

Rom 12:1 Rogo-vos pois, irmãos, pela compaixão de Deus, que apresenteis os vossos corpos como um sacrifício vivo, santo e agradável a Deus, que é o vosso culto racional.

Rom 12:2 E não vos conformeis a este mundo, mas transformai-vos pela renovação da vossa mente, para que experimenteis qual seja a boa, agradável, e perfeita vontade de Deus.
 

Referências:


José Carlos Macoratti