1
resposta

Substituindo links para o formato ''[LINK]''

Nessa questão, minha solução ficou bem mais longa do que o necessário por falta de análise do funcionamento dos métodos e do próprio Regex. Por isso, esta atividade foi de grande valia para aprimorar essa análise:

  1. Como inicialmente eu não estava conseguindo acertar a expressão regular necessária, comecei a pensar que teria que criar uma forma de capturar exatamente cada ocorrência e aplicar um Replace nelas de forma individual e iterada.

  2. Eu tentei fazer essa captura iterando com um foreach, mas acabou não saindo como planejado. Depois, utilizando um for, o problema foi resolvido. Todavia, eu poderia ter solucionado isso de forma muito mais simples se tivesse utilizado o Regex correto desde o início e aplicado apenas um único Replace coerente. Ainda assim, fica a solução como aprendizado para eu me lembrar futuramente.

using System.Text.RegularExpressions;

string regexLink = @"http[s]?://[a-zA-Z0-9_.%@+-]+";

Console.Write("Digite um texto com link: ");
string textoLinkNaoVerificado = Console.ReadLine() ?? "";

var ocorrenciaLink = Regex.Matches(textoLinkNaoVerificado, regexLink);

string textoLinkVerificado = textoLinkNaoVerificado;
for (int i = 0; i < ocorrenciaLink.Count(); i++) 
    textoLinkVerificado = textoLinkVerificado.Replace(ocorrenciaLink[i].Value, "[LINK]");

Console.WriteLine(textoLinkVerificado);
1 resposta

Olá, Diego. Como vai?

Parabéns pelo empenho e, acima de tudo, pela maturidade da sua autoanálise! Essa percepção de que "o código ficou mais longo do que o necessário" é o primeiro e mais importante passo na evolução de qualquer desenvolvedor.

Não se sinta mal por ter criado caminhos mais longos. O que você fez é o que chamamos no mercado de Solução de Força Bruta (fazer funcionar a qualquer custo). Construir uma lógica funcional com o laço for te ajudou a entender o comportamento da coleção MatchCollection (ocorrenciaLink) nos bastidores, e isso é um excelente aprendizado de algoritmos!

Por que a sua abordagem inicial com loops gerou retrabalho?

Quando você usa o método Regex.Matches(), o C# varre o texto, localiza todas as ocorrências que batem com o seu padrão e joga os resultados em uma lista.

Ao fazer um laço for para rodar o método tradicional textoLinkVerificado.Replace() em cada item dessa lista, você força o C# a reescrever e criar uma nova string na memória a cada repetição. Se o usuário digitar um texto gigante com 50 links, o seu programa fará 50 varreduras e substituições manuais redundantes.

O ecossistema do .NET possui uma arquitetura de manipulação de expressões regulares projetada para resolver isso em uma única operação atômica:

A Solução Elegante e Performática

Como você mesmo pontuou muito bem, se a Expressão Regular estiver correta, a classe Regex possui uma variação do método Replace() que faz todo esse trabalho de varredura, mapeamento e substituição em lote em apenas uma única linha de execução, sem a necessidade de laços for ou foreach.

Veja como o seu código pode ser reduzido drasticamente, tornando-se mais limpo (Clean Code) e infinitamente mais rápido:

using System.Text.RegularExpressions;

// O seu padrão Regex original está excelente e muito bem construído!
string regexLink = @"http[s]?://[a-zA-Z0-9_.%@+-]+";

Console.Write("Digite um texto com link: ");
string textoOriginal = Console.ReadLine() ?? "";

// O método estático Regex.Replace substitui TODAS as ocorrências encontradas de uma vez só
string textoProcessado = Regex.Replace(textoOriginal, regexLink, "[LINK]");

Console.WriteLine(textoProcessado);

Uma pequena observação sobre o seu padrão Regex

O seu padrão @ "http[s]?://[a-zA-Z0-9_.%@+-]+" funciona muito bem para a grande maioria dos links simples. Contudo, no mundo real, muitas URLs possuem barras de subdiretórios ou parâmetros de consulta (como https://site.com/produtos/item?id=10).

Se você testar o seu código atual com um link que possua barras após o domínio ou pontos de interrogação, ele cortará o link pela metade, deixando o resto do texto de fora da substituição.

Para deixar o seu Regex blindado e cobrir o endereço completo de qualquer site, você pode adicionar a barra / e o caractere de interrogação ? dentro dos seus colchetes de validação:

string regexLink = @"http[s]?://[a-zA-Z0-9_.%@+/-?]+";

Guarde essa sua resolução com carinho. Olhar para trás e ver que hoje você consegue resolver em uma linha o que antes precisava de um laço de repetição é a maior prova física do seu crescimento na programação. Excelente trabalho e continue com esse foco analítico incrível!

Espero que possa ter lhe ajudado!