![]() |
Hoje veremos como usar expressões regulares para localizar uma ocorrência específica em uma string usando o C#. |
A plataforma .NET vem com um poderoso mecanismo de expressões regulares que é acessível a qualquer linguagem da plataforma: VB.NET, C#, etc.
Uma expressão regular ou regex para simplificar, é um modelo que descreve uma certa quantidade de texto. A expressão regular mais simples consiste de um único caractere. Ex: a.
Este padrão irá coincidir com a primeira ocorrência do caractere em uma string. Se a string for "Isto é apenas um teste" a primeira ocorrência será a letra a antes da letra p (de apenas).
As expressões regulares possuem 11 caracteres especiais conhecidos como meta caracteres, são eles:
Para usar qualquer um destes caracteres como um literal em uma expressão regular temos que usar um caractere de escape (\). Assim se você deseja escrever 1+1=2 deverá usar 1 \+1=2 de outra forma o caractere + terá um significado especial.
A classe Regex é a classe mais importante deste grupo e qualquer código para um expressão regular instancia pelo menos um objeto desta classe ( ou usa um dos métodos estáticos da classe Regex). Você instancia este objeto passando o padrão de critério escrito no formato especial da linguagem usada para expressão regulares.
Vamos supor que você deseja localizar uma ocorrência específica de uma correspondência em uma string, como : encontrar a terceira ocorrência de uma palavra ou a segunda ocorrência de um valor número.
Podemos implementar a solução para este problema podemos subscrever um array retornado por Regex.Matches que pesquisa em uma cadeia de caracteres de entrada todas as ocorrências de uma expressão regular e retorna todas as correspondências.
Assim para localizar uma ocorrência particular podemos definir um método chamado EncontrarOcorrenciaDe():
public static Match EncontrarOcorrenciaDe(string fonte, string criterio, int ocorrencia)
{
if (ocorrencia < 1)
{
throw (new ArgumentException("Não pode ser menor que 1",nameof(ocorrencia)));
}
Regex RE = new Regex(criterio, RegexOptions.Multiline);
MatchCollection correspondencias = RE.Matches(fonte);
if (ocorrencia >= correspondencias.Count)
{
return (null);
}
else
{
return (correspondencias[ocorrencia]);
}
}
|
A seguir para localizar cada ocorrência de uma correspondência em uma string vamos criar uma lista de correspondência :
public static List<Match> EncontrarCadaOcorrenciaDe(string fonte, string criterio, int ocorrencia) { if (ocorrencia < 1) { throw (new ArgumentException("Não pode ser menor que 1", nameof(ocorrencia))); } List<Match> ocorrencias = new List<Match>();
Regex RE = new Regex(criterio, RegexOptions.Multiline);
MatchCollection correspondencias = RE.Matches(fonte);
for (int index = (ocorrencia - 1); index < correspondencias.Count; index += ocorrencia)
{
ocorrencias.Add(correspondencias[index]);
}
return (ocorrencias);
}
|
Temos aqui dois métodos semelhantes, mas distintos.
O primeiro método,
EncontrarOcorrenciaDe,
retorna uma ocorrência particular de uma correspondência de expressão regular. A
ocorrência que você deseja encontrar é passada para este método por meio do
parâmetro de ocorrência.
Se a ocorrência particular da correspondência não existe - por exemplo, você
pede para encontrar a segunda ocorrência, mas existe apenas uma ocorrência - um
nulo é retornado deste método. Por causa disso, você deve verificar se o objeto
retornado desse método não é nulo antes de usar esse objeto.
Se a ocorrência específica existir, o objeto Match
que contém as informações de correspondência para essa ocorrência é retornado.
O segundo método nesta receita,
EncontrarCadaOcorrenciaDe,
funciona de forma semelhante ao método
EncontrarOcorrenciaDe,
exceto que continua a encontrar uma ocorrência particular de uma correspondência
de expressão regular até que o final da string seja alcançado.
Por exemplo, se você pedir para encontrar a segunda ocorrência, este método
retornará um List<Match> de zero ou mais objetos
Match. Os objetos Match
corresponderiam à segunda, quarta, sexta e oitava ocorrências de uma
correspondência e assim por diante até que o final da string seja alcançado.
Para testar podemos definir o código a seguir no método Main:
static void Main(string[] args) { Match resultadoEncontrado = EncontrarOcorrenciaDe("um dois três um dois três um dois três um dois três um dois três um dois três", "dois", 2); Console.WriteLine($"{resultadoEncontrado?.ToString()}\t{resultadoEncontrado?.Index}"); Console.WriteLine(); List<Match> resultados = EncontrarCadaOcorrenciaDe("um um dois três um dois três um dois três um dois três", "um", 3);
foreach (Match m in resultados)
Console.ReadLine(); |
Executando o
projeto teremos o resultado abaixo:
Pegue o projeto completo aqui :
CShp_Regex1.zip
"E não comuniqueis
com as obras infrutuosas das trevas, mas antes condenai-as. Porque o que eles
fazem em oculto até dizê-lo é torpe. Mas todas estas coisas se manifestam, sendo
condenadas pela luz, porque a luz tudo manifesta."
Efésios 5:11-13
Referências:
ADO .NET - Acesso Assíncrono aos dados -
C# - Programação Funcional - Exemplos
C# - Coleções Imutáveis - Macoratti
C# 9.0 - Apresentando Records -
C# - Os 10 Erros mais comuns dos iniciantes
C# - Otimizando o código