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!