|
Neste tutorial vou mostrar como podemos usar os recursos da LINQ - Language Integrated Query - para tratar strings e coleções de strings. |
A LINQ pode ser usada para consultar e transformar strings e coleções de strings, e, este recurso pode ser muito útil, especialmente com dados estruturados em arquivos textos.
Podemos combinar as consultas LINQ com as funções strings tradicionais e com expressões regulares aumentando assim o seu potencial de recursos. Dessa forma podemos:
Usar o método Split() para criar um array de strings que podemos consultar e modificar usando LINQ e também podemos usar usar o método IsMatch() na cláusula Where da consulta LINQ.
Usar a LINQ para consultar ou modificar o resultado MatchCollection retornado por uma expressão regular.
Assim podemos separar um texto fonte em palavras, sentenças, parágrafos, paginas e qualquer outro critério e então realizar consulta adicional.
Muitos tipos de arquivos textos consistem em uma série de linhas, com uma formatação padrão que usa vírgula, tab, arquivos delimitados, arquivos fixo, etc. Após você ler esses arquivos você pode usar a LINQ para consultar e modificar as linhas.
Esse artigo será útil para recordar os recursos da LINQ no tratamento de strings.
Recursos usados:
Nota: Baixe e use a versão Community 2015 do VS ela é grátis e é equivalente a versão Professional.
Criando o projeto no VS Community
Abra o VS 2015 Community e clique em New Project;
Selecione a linguagem Visual Basic e o template Windows Forms Application;
Informe o nome da solução como LINQ_Strings e clique no botão OK;
1 - Contando as ocorrências de uma palavra em uma string
Como a classe string implementa a interface genérica IEnumerable(Of T), qualquer string pode ser consultada como uma sequência de caracteres. (Para operações mais complexas é aconselhável usar Regex)
Neste exemplo mostra como podemos usar uma consulta LINQ para contar as ocorrências de uma palavra especificada em uma string.
Para realizar a tarefa primeiro usamos o método Split para criar um array de palavras e isso tem um impacto no desempenho da aplicação, portanto se a única tarefa é contar palavras poderíamos usar os métodos Matches ou IndexOf.
Defina no formulário form1.vb os controles:
1 Button - btnLerTexto
1 TextBox - txtText, Multiline=True
1 Button - btnContarOcorrencias
1 Textbox - txtPalavra
1 Button - btnLimpar
1 ListBox - lbResultado
Disponha os controles no formulário conforme o leiaute da figura abaixo:
No evento Click do botão - btnLerTexto inclua o código que permite escolher um arquivo texto e exibir no formulário:
Private Sub btnLerTexto_Click(sender As Object, e As EventArgs) Handles btnLerTexto.Click Dim ofd1 As New OpenFileDialog ofd1.Title = "Selecionar Arquivo" ofd1.InitialDirectory = "C:\Dados\" 'filtra para exibir somente arquivos textos ofd1.Filter = "Arquivos Texto (*.Txt)|*.Txt|" & "Todos Arquivos (*.*)|*.*" ofd1.CheckFileExists = True ofd1.CheckPathExists = True ofd1.FilterIndex = 1 ofd1.RestoreDirectory = True ofd1.ReadOnlyChecked = True Dim dr As DialogResult = ofd1.ShowDialog() If dr = System.Windows.Forms.DialogResult.OK Then ' abre o arquivo e le o seu conteudo txtTexto.Text = My.Computer.FileSystem.ReadAllText(ofd1.FileName) End If End Sub |
No evento Click do botão - btnContarOcorrencias - inclua o código que irá contar o número de ocorrências da palavra informada:
Private Sub btnContarOcorrencias_Click(sender As Object, e As EventArgs) Handles btnContarOcorrencias.Click Dim palavraAlvo As String = txtPalavra.Text.Trim() If String.IsNullOrWhiteSpace(palavraAlvo) Then MessageBox.Show("Informe a palavra a ser contada na string") Exit Sub End If Dim fonteDados As String() = txtTexto.Text.Split(New Char() {" ", ",", ".", ";", ":", "-", ", ", "(", ")"}, StringSplitOptions.RemoveEmptyEntries) ' Cria e executa a consulta ' Ela é executada imediatamente porque um único valor é produzido ' Usamos ToLower para encontrar "xxx" e "XXX" Dim resultado = From palavra In fonteDados Where palavra.ToLowerInvariant() = palavraAlvo.ToLowerInvariant() Select palavra 'conta as ocorrências Dim valor As Integer = resultado.Count() 'exibe o resultlado o listbox lbResultado.Items.Add(valor & " ocorrência da palavra """ & palavraAlvo & """ foram encontradas.") End Sub |
Executando o projeto e fazendo alguns testes teremos o resultado abaixo:
2 - Combinando Consultas LINQ com expressões regulares
Vamos realizar agora uma consulta mais complexa usando LINQ e expressões regulares.
Vamos supor que desejamos verificar a ocorrência de uma palavra em arquivos HTML (.htm).
Vamos incluir um novo formulário no projeto atual e definir uma interface simples e intuitiva usando os seguintes controles:
1 TextBox - txtLocal
1 Button - btnLocalBusca
1 TextBox - txtPalavra
1 Button - btnOcorrencias
1 ListBox - lbResultado
No evento Click do botão btnLocalBusca inclua o código que permite selecionar uma pasta a partir de onde serão lidos os arquivos para realizar a busca:
Private Sub btnLocalBusca_Click(sender As Object, e As EventArgs) Handles btnLocalBusca.Click Dim fbd1 As New FolderBrowserDialog fbd1.Description = "Selecione uma pasta para busca" fbd1.RootFolder = Environment.SpecialFolder.MyComputer fbd1.ShowNewFolderButton = True 'Exibe a caixa de diálogo If fbd1.ShowDialog = DialogResult.OK Then 'Exibe o nome da pasta no textbox txtLocal.Text = fbd1.SelectedPath.ToString() End If End Sub |
A seguir no evento Click do botão - btnOcorrencias - temos o código que percorre todos os arquivos com extensão .htm da pasta e faz a busca por ocorrências nos arquivos da palavra definida para critério de busca:
Private Sub btnOcorrencias_Click(sender As Object, e As EventArgs) Handles btnOcorrencias.Click Dim pastaBusca As String = txtLocal.Text.Trim Dim listaArquivos As IEnumerable(Of FileInfo) = ObtemArquivos(txtLocal.Text.Trim) ' Cria uma expressão regular para encontrar as ocorrências do texto indicado Dim termoBusca As System.Text.RegularExpressions.Regex = New System.Text.RegularExpressions.Regex(txtPalavra.Text.Trim) 'define a consulta nos arquivos .htm do texto indicado Dim consultaArquivos = From _arquivo In listaArquivos Where _arquivo.Extension = ".htm" Let arquivoTexto = File.ReadAllText(_arquivo.FullName) Let correspondencia = termoBusca.Matches(arquivoTexto) Where (correspondencia.Count > 0) Select Name = _arquivo.FullName, Matches = From match As System.Text.RegularExpressions.Match In correspondencia Select match.Value ' Executa a consulta lbResultado.Items.Add("O termo " & termoBusca.ToString() & " foi encontrado em :") For Each arquivosCoincidentes In consultaArquivos Dim s = arquivosCoincidentes.Name.Substring(pastaBusca.Length - 1) lbResultado.Items.Add(s) For Each encontrado In arquivosCoincidentes.Matches lbResultado.Items.Add(" " + encontrado) Next Next End Sub |
Abaixo temos o código do método ObtemArquivos que recebe a pasta de destino e obtém os arquivos contidos nesta pasta:
Shared Function ObtemArquivos(ByVal raiz As String) As IEnumerable(Of System.IO.FileInfo) Return From arquivo In My.Computer.FileSystem.GetFiles( raiz, FileIO.SearchOption.SearchAllSubDirectories, "*.*") Select New FileInfo(arquivo) End Function |
Executando o projeto e fazendo alguns testes teremos o resultado abaixo:
Dessa forma vimos como usar os recursos do LINQ para tratar strings e coleções.
Pegue o projeto completo aqui : LINQ_Strings.zip
Porque há um só Deus, e um só Mediador entre Deus e os homens, Jesus Cristo
homem.
1 Timóteo 2:5
Veja os
Destaques e novidades do SUPER DVD Visual Basic
(sempre atualizado) : clique e confira !
Quer migrar para o VB .NET ?
Quer aprender C# ??
Quer aprender os conceitos da Programação Orientada a objetos ? Quer aprender o gerar relatórios com o ReportViewer no VS 2013 ? Quer aprender a criar aplicações Web Dinâmicas usando a ASP .NET MVC 5 ? |
Gostou ? Compartilhe no Facebook Compartilhe no Twitter
Referências:
Super DVD Vídeo Aulas - Vídeo Aula sobre VB .NET, ASP .NET e C#
Tratamento de erros usando Try-Catch-Finally - Macoratti.net
NET - LINQ a seu dispor - Sintaxe e Operadores - Macoratti ...