Compartilhar via


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