This article has been localized into Portuguese by the community.
Buscando/Substituindo com a classe Regex
Já discutimos a classe Regex e como usá-la quando queremos pesquisar por uma string em um artigo anterior. Expressões regulares são ótimas para isso, mas outro caso de uso é quando você deseja executar operações de pesquisa/substituição, onde deseja procurar um padrão específico e substituí-lo por outra. A classe String já possui um método Replace(), mas isso é bom apenas para pesquisas simples. Ao usar Expressões Regulares, você pode usar o poder das pesquisas de regex e até mesmo usar grupos capturados como parte da sequência de substituição. Soa complicado? Não se preocupe, começaremos com um exemplo simples e, em seguida, trabalharemos lentamente para casos de uso mais avançados.
Como no artigo anterior, todos os exemplos assumem que você importou o namespace RegularExpressions, assim:
using System.Text.RegularExpressions;
Com isso, vamos tentar trabalhar com a substituição de strings baseadas em expressões regulares. Usaremos o método Replace() encontrado na classe Regex :
string testString = "<b>Hello, <i>world</i></b>";
Regex regex = new Regex("<[^>]+>");
string cleanString = regex.Replace(testString, "");
Console.WriteLine(cleanString);
Este exemplo exibe uma abordagem muito simplificada para remover tags HTML de uma string. Combinamos tudo o que é cercado por um conjunto de colchetes angulares (& lt; & gt;) e, em seguida, usamos o método Replace() para substituir cada ocorrência por uma cadeia vazia, basicamente removendo as tags HTML da cadeia de teste.
Substituindo por Valores Capturados
Mas digamos que você não queira realmente removê-los, mas, em vez disso, deseja transformar as tags em algo que não será interpretado por um navegador, por exemplo, substituindo os colchetes angulares (& lt; & gt;) por colchetes ([]). É aí que as Expressões Regulares realmente mostram seu poder, porque na verdade é muito fácil, conforme ilustrado por esta versão ligeiramente reescrita do nosso exemplo anterior:
string testString = "<b>Hello, <i>world</i></b>";
Regex regex = new Regex("<([^>]+)>");
string cleanString = regex.Replace(testString, "[$1]");
Console.WriteLine(cleanString);
Na verdade, acabei de alterar dois detalhes menores: adicionei um par de parênteses à regex para criar um grupo de captura, essencialmente capturando o valor entre os colchetes angulares no primeiro grupo de captura. No método Replace() , faço referência a isso usando a notação especial $ 1 , que basicamente significa apenas número de grupo de captura 1. Com isso, nossa saída agora será semelhante a esta :
[b]Hello, [i]world[/i][/b]
Grupos de captura nomeados
Você pode fazer exatamente a mesma coisa ao usar grupos de captura nomeados (discutidos no artigo anterior), assim:
string testString = "<b>Hello, <i>world</i></b>";
Regex regex = new Regex("<(?<tagName>[^>]+)>");
string cleanString = regex.Replace(testString, "[${tagName}]");
Console.WriteLine(cleanString);
Ao usar grupos de captura nomeados, basta usar a notação $ {name-of-capture-group} .
Usando um método MatchEvaluator
Mas se quisermos ainda mais controle sobre como o valor é substituído? Podemos usar um parâmetro MatchEvaluator para isso - é basicamente apenas uma referência (delegada) a um método que será chamado toda vez que uma substituição for feita, permitindo que você modifique o valor de substituição antes de usá-lo. Vamos ficar com o exemplo de tags HTML que já usamos algumas vezes, mas, desta vez, assumimos o controle sobre quais tags HTML são usadas. Aqui está o exemplo completo:
using System;
using System.Text.RegularExpressions;
namespace RegexSearchReplaceMethod
{
class Program
{
static void Main(string[] args)
{
string testString = "<b>Hello, <i>world</i></b>";
Regex regex = new Regex("<(?<tagName>[^>]+)>");
string cleanString = regex.Replace(testString, ProcessHtmlTag);
Console.WriteLine(cleanString);
}
private static string ProcessHtmlTag(Match m)
{
string tagName = m.Groups["tagName"].Value;
string endTagPrefix = "";
if(tagName.StartsWith("/"))
{
endTagPrefix = "/";
tagName = tagName.Substring(1);
}
switch (tagName)
{
case "b":
tagName = "strong";
break;
case "i":
tagName = "em";
break;
}
return "<" + endTagPrefix + tagName.ToLower() + ">";
}
}
}
A primeira parte do exemplo é exatamente como antes, mas em vez de fornecer uma string de substituição, passamos uma referência ao nosso método ProcessHtmlTag() . Como mencionado, esse método é chamado toda vez que uma substituição está prestes a ser feita, com o Match em questão como um parâmetro. Isso significa que, em nosso método MatchEvaluator, temos todas as informações sobre a correspondência para que possamos agir de acordo. Neste caso, usamos essa oportunidade para tornar as tags mais semânticas, substituindo a tag bold (b) por uma tag forte e a tag italic (i) por uma tag emphasis (em). Não importa se a tag foi alterada ou não, a transformamos em minúscula.
Usar um parâmetro MatchEvaluator é obviamente muito poderoso e isso é apenas um exemplo simples do que pode ser realizado.
Resumo
Operações de busca/substituição tornam-se muito poderosas quando você usa Expressões Regulares e ainda mais quando você usa o parâmetro MatchEvaluator, onde as possibilidades de manipulação de strings tornam-se quase infinitas.