Mostrando postagens com marcador STRING. Mostrar todas as postagens

terça-feira, 10 de janeiro de 2017

[Debug] Comparar/Listar Strings acentuadas usando Collactor

Fala galera que acompanha o blog...   
   
Quando estamos trabalhando com strings, sempre nos deparamos com problemas clássicos, como por exemplo, comparar strings maiúsculas com minúsculas, acentuadas, com codificação diferente e até mesmo na hora de listar essas strings ordenando de forma crescente ou decrescente e por ai em diante.  
   
[Debug] Comparar/Listar Strings acentuadas usando Collactor


Nesse post eu vou estar ensinando uma forma de comparar strings acentuadas utilizando o Collactor. Acredite ou não, no Java existe uma classe que realiza essa comparação ignorando os acentos.   

Vamos utilizar como exemplo o meu nome Luíz Fágner Zordan, mas é claro que a forma original é sem acento algum. Veja essas premissas:   
 
Luíz Fágner Zordan e Luiz Fagner Zordan são as mesmas pessoas, o que difere são os acentos;   
Luiz Fágner Zordan e LUÍZ FÁGNER ZORDAN são as mesmas pessoas, o que difere são os acentos e as letras maiúsculas;   
Luiz Fágner Zordan e Luiz Vagner Zordan não são as mesmas pessoas;   
   
Veja esse código:   
 
class CollatorEmAcao { 

    public static void main(String[] args) { 

        // Compara Strings, ignorando os acentos 

        String st1 = "Luíz Fágner Zordan"; 

        String st2 = "Luiz Fagner Zordan "; 

        String st3 = "LUÍZ FÁGNER ZORDAN"; 

        String st4 = "Luiz Vagner Zordan"; // Perceba que o nome está escrito errado 
  

        Collator collator = Collator.getInstance (new Locale ("pt", "BR")); 

        collator.setStrength(Collator.PRIMARY);     

        if (collator.compare (st1, st2) == 0) { 

            System.out.println ("Os dois Fagner são as mesmas pessoas, o que difere são os acentos"); 

        } 

        if (collator.compare (st1, st3) == 0) { 

            System.out.println ("Os dois Fagner são as mesmas pessoas, o que difere são os acentos e as letras maiúsculas"); 

        } 

        if (collator.compare (st1, st4) != 0) { 

            System.out.println ("Os dois Fagner não são as mesmas pessoas"); 

        } 

} 



Bom, vimos como comparar strings ignorando os acentos, agora vamos ordenar as strings, ignorando os acentos. Para essa segunda parte vejam o seguinte exemplo:   
 
class CollactorEmAcao{ 

    public static void main(String[] args) { 

        // Ordena String, ignorando os acentos. 

        String[] nomes = { 

            "José Aparecido", 

            "João Simões", 

            "Jó Abedenego"   

        };   

        // Sem o uso de "collator" o resultado deve ser: 

       //  [José Aparecido, João Simões, Jó Abedenego] 

       //  que é o contrário da língua portuguesa 

        SortedSet<String> st1 = new TreeSet<String>(); 

        for (String nome : nomes) { 

            st1.add (nome); 

        } 

        System.out.println (st1); 

        // Usando "collator", o resultado deve ser: 

        // [Jó Abedenego, João Simões, José Aparecido] 

        final Collator coll = Collator.getInstance (new Locale ("pt", "BR")); 

  
        SortedSet<String> st2 = new TreeSet<String>(new Comparator<String>() { 

            public int compare (String s1, String s2) { 

                return coll.compare (s1, s2); 

            } 

        }); 

        for (String nome : nomes) { 

            st2.add (nome); 

        } 

        System.out.println (st2); 

    } 

}

Sem o uso do Collactor, não é respeitada as normas corretas de ordenação, por isso a ordenação acaba ficando "errada".

É isso ai pessoal, até a próxima

sexta-feira, 9 de dezembro de 2016

[Debug] Remover acentos utilizando Normalize

Fala galera que acompanha o blog...

Estava criando uma classe de utilitários, que logo pretendo disponibilizar aqui no blog, e acabei encontrando uma forma muito elegante de remover acentos de uma string utilizando o Normalize.




Se você pesquisar algo como "como remover acentos de uma string", vai perceber que existem diversas formas de faze-lo, usando arrays, mapa de caracteres, usando a biblioteca Apache Commons Lang, replaceAll com regex, indexOf() e várias outras formas. No entanto a classe Normalize, foi a que me chamou mais atenção, veja o código abaixo:

package com.devic.main;
import java.text.Normalizer;
public class Main {

 public static void main(String[] args) {
 String entrada = "çÇáéíóúýÁÉÍÓÚÝàèìòùÀÈÌÒÙãõñäëïöüÿÄËÏÖÜÃÕÑâêîôûÂÊÎÔÛ";
 System.out.println(Normalizer.normalize(entrada, Normalizer.Form.NFKD).replaceAll("\\p{InCombiningDiacriticalMarks}+", ""));
 }
}

Saida:

cCaeiouyAEIOUYaeiouAEIOUaonaeiouyAEIOUAONaeiouAEIOU

Bonito, não?

Esse trecho de código possui duas etapas:

  • Normalizar a nossa string seguindo o tipo de normalização enviado como parâmetro;
  • Realizar o replace de todos os caracteres normalizados para a sua forma normal.
Vamos ver outro código para entender melhor o que está acontecendo:

String entrada = "aáeéiíoóöőuúüű AÁEÉIÍOÓÖŐUÚÜŰ";
for (int i = 0; i < entrada.length(); i++) {
 
  // nos iremos escrever cada caracter separado, para visualizar melhor como ele funciona
  String texto = original.substring(i, i + 1);
 
  // realizando a normalização
  String decomposto = Normalizer.normalize(texto, Form.NFD);
  // removing diacritics
  String removido = decomposto.replaceAll("\\p{InCombiningDiacriticalMarks}+", "");

 System.out.println(texto + " (" + asHex(texto) + ") -> "
 + decomposto + " (" + asHex(decomposto) + ") -> "
 + removido + " (" + asHex(removido) + ")");
}


E a saída, ficará assim:

a (0061     ) -> a (0061     ) -> a (0061     )

á (00e1     ) -> á (0061 0301) -> a (0061     )

e (0065     ) -> e (0065     ) -> e (0065     )

é (00e9     ) -> é (0065 0301) -> e (0065     )

i (0069     ) -> i (0069     ) -> i (0069     )

í (00ed     ) -> í (0069 0301) -> i (0069     )

o (006f     ) -> o (006f     ) -> o (006f     )

ó (00f3     ) -> ó (006f 0301) -> o (006f     )

ö (00f6     ) -> ö (006f 0308) -> o (006f     )

ő (0151     ) -> ő (006f 030b) -> o (006f     )

u (0075     ) -> u (0075     ) -> u (0075     )

ú (00fa     ) -> ú (0075 0301) -> u (0075     )

ü (00fc     ) -> ü (0075 0308) -> u (0075     )

ű (0171     ) -> ű (0075 030b) -> u (0075     )

  (0020     ) ->   (0020     ) ->   (0020     )

A (0041     ) -> A (0041     ) -> A (0041     )

Á (00c1     ) -> Á (0041 0301) -> A (0041     )

E (0045     ) -> E (0045     ) -> E (0045     )

É (00c9     ) -> É (0045 0301) -> E (0045     )

I (0049     ) -> I (0049     ) -> I (0049     )

Í (00cd     ) -> Í (0049 0301) -> I (0049     )

O (004f     ) -> O (004f     ) -> O (004f     )

Ó (00d3     ) -> Ó (004f 0301) -> O (004f     )

Ö (00d6     ) -> Ö (004f 0308) -> O (004f     )

Ő (0150     ) -> Ő (004f 030b) -> O (004f     )

U (0055     ) -> U (0055     ) -> U (0055     )

Ú (00da     ) -> Ú (0055 0301) -> U (0055     )

Ü (00dc     ) -> Ü (0055 0308) -> U (0055     )

Ű (0170     ) -> Ű (0055 030b) -> U (0055     )


É isso ai pessoal, espero que tenham gostado e que seja bastante útil ai no projeto de vocês.

Até a próxima!

terça-feira, 26 de julho de 2016

Debug #9 - Função strTran() - Advpl

Fala galera!

Hoje falaremos um pouco sobre a função strTran(). Essa função é muito útil para quem precisa alterar uma string, onde precisa retirar ou substituir caracteres específicos.



A função possui 5 parâmetros, porém somente 2 são obrigatórios. Vamos analisá-lo:

TDN Totvs - StrTran

O retorno é uma nova string com os caracteres substituídos. Antes de utilizar, é preciso atentar-se a algumas observações:
  • a função é case sensitive;
  • se o campo cReplace não for informado, os caracteres ficarão vazios;
  • se omitido o campo nStart, o valor padrão (1) será utilizado;
  • se omitido o campo nCount, todos os caracteres encontrados serão substituídos.
Veja um exemplo:

user function strTran
      
private cString := "123 123 123 123"
private cNovaString := ""                      

cNovaString := strTran(cString, "1"  , "4")

msgInfo("String original: " + cString + CHR(10) + CHR(13) +;
  "String nova: "+ cNovaString)

return           

E abaixo está o resultado:


Simples, não? Espero que seja útil esta dica.

Fonte: TDN Totvs

Até mais!

;)

quinta-feira, 5 de maio de 2016

Debug #6 - Recuperar o ultimo valor com split

O método split é utilizado quando é necessário quebrar uma String em várias substrings.

Veja o seguinte código:
public static void main(String[] args) {
        
        // Como entrada temos um diretorio separado por / barra
        String entrada = "C:/Users/Faguinho/Videos/Seriados/Vikings";
                
        // Vamos quebrar nossa entrada em várias substrings
        // usando / para identificar onde nossa string deverá ser quebrada
        // e armaze-las em um vetor de String
        String[] saida = entrada.split("/");
        
        // Esse laço de repetição está pegando cada nova string gerada
        // a partir da nossa string de entrada, e varrendo todo vetor
        // escrevendo na tela a substring armazenada
        for (String substring : saida) {
            System.out.println(substring);
        }
    }

E teremos a seguinte saida:
C:
Users
Faguinho
Videos
Seriados
Vikings
Acabamos de pegar um determinado diretório e separa-lo em várias pastas até chegar na nossa pasta final que é "Vikings" (uma série muito boa, assistam rs).


Debug 6 - Recuperar o ultimo valor com split


Nos usamos o separador "/" para quebras nossa String, mas poderíamos estar usando qualquer marcador para identificar onde nossa String deveria ser quebrada.
Muitas vezes se faz necessários resgatar o ultimo valor de uma String, e para isso existem inúmeras formas de faze-lo um exemplo clássico é o seguinte código:
public static void main(String[] args) {

        String entrada = "C:/Users/Faguinho/Videos/Seriados/Vikings";
        String[] saida = entrada.split("/");
        
        // Criamos uma variavel do tipo String e a inicializamos com null
        String resultado = null;

        // Nesse laço estamos inicializando nossa variavel em 1
        // iremos ficar repetindo esse código enquanto i for menor que a quantidade
        // de substring armazenadas em nosso vetor saida
        // e estamos informando que nosso laço deve somar 1 a cada execução
        for (int i = 1; i < saida.length; i++) {
            resultado = saida[i];
        }
        
        // E aqui escrevemos o nosso resultado
        System.out.println(resultado);
    }

E teremos a saída: "Vikings"

Mas esse exemplo deixa o código extenso, processando todo um vetor para recuperar o último valor, não é nada bom.

Para resolver esse tipo de problema podemos usar o seguinte código:
public static void main(String[] args) {

        String entrada = "C:/Users/Faguinho/Videos/Seriados/Vikings";
        String resultado = entrada.split( "/" )[entrada.split( "/" ).length - 1];
        
        System.out.println(resultado);
    }

Ficou bonito não? rs
Com apenas uma linha resolvemos todos o nosso problema. Vamos a explicação!

Estamos usando matemática para resolver o nosso problema, então primeiro começaremos pelas [], ou seja nosso segundo split: [entrada.split( "/" ).length - 1], estamos simplesmente verificando a quantidade de substrings geradas menos um.
No nosso exemplo teremos o resultado = 5

A expressão ficou igual a entrada.split( "/" )[5], dessa forma o método split remove todos os valores anteriores e recupera apenas o valor que fica logo após a quinta barra.

Execute esse trecho: entrada.split( "/" )[5], e teremos a nossa saída = Vikings
Execute esse trecho: entrada.split( "/" )[4], e teremos a nossa saída = Seriados
Execute esse trecho: entrada.split( "/" )[2], e teremos a nossa saída = Users

Bom, como eu disse existem várias formas de resolver esse problema, e essa é uma das formas que eu uso nos meus códigos.

Até a próxima.