Normalização de texto em .NET: removendo caracteres especiais de uma string
O objetivo deste artigo é apresentar uma solução para a normalização de strings em .NET, com a consequente remoção de caracteres especiais como acentos, cedilha e símbolos oriundos de línguas estrangeiras em sequências de texto.
Introdução
A necessidade de efetuar alguma forma de tratamento em sequências de texto corresponde a um tipo de situação extremamente comum em sistemas corporativos. Demandas como esta são mais frequentes em cenários de integração com instituições bancárias ou órgãos governamentais, nos quais exigências quanto à substituição de caracteres como acentos, cedilha e outros símbolos representam uma prática comum.
Normalizar uma string implicará, sempre que possível, na troca de símbolos gráficos por letras do alfabeto latino ou outro sinal compatível com a codificação ASCII. No caso específico da plataforma .NET, uma das soluções disponíveis passa pelo uso de recursos definidos nos namespaces System.Text e System.Globalization.
O objetivo deste artigo é demonstrar justamente este processo de normalização de textos em .NET, através da implementação de um exemplo que será detalhado nas próximas seções.
Implementando a funcionalidade para normalização de texto
Para implementar os projetos demonstrados nesta e na próxima seção foram utilizados os seguintes recursos:
- O Microsoft Visual Studio Professional 2013 Update 4 como IDE de desenvolvimento;
- O .NET Framework 4.5.1.
A solução descrita neste artigo foi disponibilizada no Technet Gallery, podendo ser baixada a partir do link:
https://gallery.technet.microsoft.com/Extraindo-caracteres-aba4bb0e
A Solution a ser criada terá por nome “NormalizeText”, conforme é possível visualizar na próxima imagem:
O próximo passo será a criação de uma Class Library chamada “String.Extensions”, como indicado a seguir:
No projeto String.Extensions estará a classe NormalizeTextExtension, cuja implementação pode ser observada na próxima listagem. Quanto à definição deste tipo estático deve-se destacar:
- A presença de um Extension Method chamado RemoveSpecialCharacters. Em termos práticos, um Extension Method nada mais é do que um método estático codificado de forma convencional, muito embora um desenvolvedor possa enxergá-lo como uma operação acessível a partir da instância de uma classe pré-existente (a qual é indicada obrigatoriamente por um parâmetro cujo tipo vem precedido pela palavra-chave “this”). Este tipo de construção descarta a necessidade de criação de um tipo derivado, servindo como um meio para “adicionar” novos recursos a uma estrutura já definida anteriormente. No exemplo aqui discutido está sendo implementada uma extensão que associa uma nova funcionalidade à classe String (por meio do parâmetro “text”);
- Uma instância do tipo StringBuilder (namespace System.Text) será criada no início de RemoveSpecialCharacters, O objeto criado será associado à referência “sbReturn” para utilização posterior;
- Na sequência as operações Normalize (que recebe o valor de enumeration NormalizationForm.FormD) e ToCharArray serão invocadas, a partir da instância do tipo String associada a “text”. O retorno desta ação será um array de caracteres normalizados;
- Este mesmo array servirá de base para a montagem de uma nova string. Tal processo fará uso do objeto StringBuilder vinculado à variável sbReturn, com a adição de caracteres a esta instância acontecendo desde que cada posição corresponda a um símbolo válido (esta checagem envolve uma chamada à operação GetUnicodeCategory do tipo CharUnicodeInfo, de forma que o valor obtido seja diferente de UnicodeCategory.NonSpacingMark);
- Por fim, o conteúdo da variável sbReturn será devolvido como resultado da execução do método RemoveSpecialCharacters.
using System.Text;
using System.Globalization;
namespace String.Extensions
{
public static class NormalizeTextExtension
{
/// <summary>
/// Remove caracteres especiais de uma string, substituindo os mesmos
/// por letras quando possível.
/// </summary>
/// <param name="text">Texto a ser tratado.</param>
/// <returns>Nova string com caracteres especiais removidos.</returns>
public static string RemoveSpecialCharacters(this string text)
{
StringBuilder sbReturn = new StringBuilder();
var arrayText =
text.Normalize(NormalizationForm.FormD).ToCharArray();
foreach (char letter in arrayText)
{
if (CharUnicodeInfo.GetUnicodeCategory(letter) !=
UnicodeCategory.NonSpacingMark)
sbReturn.Append(letter);
}
return sbReturn.ToString();
}
}
}
Testes
Dando andamento à demonstração sobre como normalizar sequências de texto em .NET, será criada agora uma Console Application chamada “String.Extensions.Tests”:
Este novo projeto deverá referenciar a Class Library implementada na seção anterior, conforme é possível observar na próxima imagem:
O código que define a classe Program está na próxima listagem:
- Um array com strings apresentando acentuação (referência “jogadoresAlemanha2014”) é criado logo no início do método Main;
- Uma primeira chamada ao método ShowArray fará com que o conteúdo do array jogadoresAlemanha2014 seja impresso em tela;
- Um novo array será associado à variável jogadoresAlemanha2014, a partir da invocação dos métodos Select e ToArray. Na prática, os valores iniciais serão atualizados ao se acionar o método RemoveSpecialCharacters a cada item retornado por Select. Após este procedimento será invocada a operação ShowArray mais uma vez, de forma a exibir em tela o novo conteúdo da referência jogadoresAlemanha2014.
using System;
using System.Linq;
using System.Text;
namespace String.Extensions.Tests
{
class Program
{
private static void ShowArray(string[] array)
{
StringBuilder strb = new StringBuilder();
strb.Append("[ ");
foreach (string item in array)
{
if (strb.Length > 2)
strb.Append(" , ");
strb.Append(item);
}
strb.Append(" ]");
Console.WriteLine(
"Conteúdo do array = {0}",
strb.ToString());
}
static void Main(string[] args)
{
string[] jogadoresAlemanha2014 =
{
"Jérôme Boateng",
"André Schürrle",
"Mario Götze"
};
ShowArray(jogadoresAlemanha2014);
jogadoresAlemanha2014 = jogadoresAlemanha2014
.Select(j => j.RemoveSpecialCharacters()).ToArray();
Console.WriteLine("\nApós o tratamento do texto:");
ShowArray(jogadoresAlemanha2014);
Console.ReadKey();
}
}
}
Uma última observação deve ser feita quanto à utilização de Extension Methods no Visual Studio. O IntelliSense entenderá que o método em questão é parte integrante da classe para a qual o mesmo foi definido, como indicado na próxima imagem (desde que o namespace em que consta tal Extension Method tenha sido declarado entre os “usings” do arquivo de código-fonte):
Concluída a implementação desta aplicação de testes, será necessário executar o projeto String.Extensions.Tests. Ao se fazer isto aparecerá como resultado a seguinte tela:
Conclusão
Conforme detalhado no exemplo prático deste artigo, a normalização de texto em aplicações .NET pode ser obtida a partir da utilização de recursos existentes nos namespaces System.Text e System.Globalization. O comum em tais casos é que os caracteres sejam substituídos por representações ASCII equivalentes, característica comumente exigida por projetos voltados à integração de dados.
Referências
Char.GetUnicodeCategory Method (Char)
https://msdn.microsoft.com/en-us/library/hz49h034%28v=vs.110%29.aspx
Extension Methods (C# Programming Guide)
https://msdn.microsoft.com/en-us/library/bb383977.aspx
String.Normalize Method (NormalizationForm)
https://msdn.microsoft.com/en-us/library/ebza6ck1(v=vs.110).aspx