Regex

Olá pessoal,

eu tava discutindo com um colega aqui do forum sobre busca por strings em listas neste post:

Gostaria de saber como eu poderia fazer uma busca que não diferenciasse letras maiusculas de minusculas, acentuadas de não acentuadas.

Se eu utilizar o contains sugerido pelo colega, não pegaria todas as strings.

Mas se eu utilizasse regex, eu teria que pegar letra por letra da string buscada e ir contruindo minha string de regex.
Algo do tipo:

string de busca digitada:

regex para a busca:
[pP][aAáÁãÃàÀäÄ]

Meu regex ficaria gigantesco e ainda poderia ter um problema quanto ao tempo de busca.
Alguem tem uma idéia melhor?

Acho que não tem como eu fazer isso de forma melhor que utilizando um banco de dados com a colation correta.

Aqui vai um exemplo:



package filmes2;

import java.util.ArrayList;


public class Filmes2
{

    public static void main(String[] args)
    {
        ArrayList<String> filmes;
        filmes = new ArrayList<String>();
        filmes.add("programacao");
        filmes.add("programaçao");
        filmes.add("programação");
        filmes.add("programacão");
        filmes.add("Programacao");
        filmes.add("Programaçao");
        filmes.add("Programação");
        filmes.add("Programacão");

        System.out.println("teste 1:");  
        System.out.println("________________________________");  
        for (String l : filmes)
        {
            if (l.contains("programaçao"))
            {
                System.out.println(l);  
            }
        }
        
        System.out.println("teste 2:");  
        System.out.println("________________________________");  
        for (String l : filmes)
        {
            if (l.matches("^[pP]rograma[çc][aã]o$"))
            {
                System.out.println(l);  
            }
        }
    }
}

seria mais facil vc a cada palavra fazer o toLowerCase() na palavra que vem e depois fazer a procura com regex, assim voce evita fazer comparaçoes desnecessarias adicionais

lembrando que se vc fizer somente o palavra.toLowerCase(); e depois mandar fazer a busca vai da erro pois dessa forma é imutavel…

vc vai ter que fazer algo como…

String palavraAux = palavra.toLowerCase();

e usar palavraAux no regex

Veja o post do Thingol aqui:

[quote=ViniGodoy]Veja o post do Thingol aqui:

[/quote]

Cara, adorei!
Esse thingol é mesmo fodastico!!! :smiley:
vou colocar no meu favoritos.

Valeu ViniGodoy! :thumbup:

To postando as classes que criei.
Se alguem tiver alguma dica, sou todo “olhos”. :smiley:

Será que tem como combinar o Collator.compare com um regex ou um contains?

Classe da minha lógica:


import java.util.*;
import java.text.*;

public class FilmesBu
{

    private Collator collator;
    private SortedSet<String> lista;

    public FilmesBu()
    {
        collator = Collator.getInstance(new Locale("pt", "BR"));
        collator.setStrength(Collator.PRIMARY); // importante!
        lista = new TreeSet<String>(new Comparator<String>()
        {

            @Override
            public int compare(String o1, String o2)
            {
                return collator.compare(o1, o2);
            }
        });
    }

    public SortedSet<String> selecionar(String palavra)
    {
        SortedSet<String> selecionadas = new TreeSet<String>();

        for (String d : lista)
        {
            // queria utilizar o collator.compare com um contains ou um regex
            for (int i = 0; i <= d.length() - palavra.length(); i++)
            {
                //teste
                //System.out.println( d.substring(i, i+palavra.length()));
                if (collator.compare(d.substring(i, i + palavra.length()), palavra) == 0)
                {
                    selecionadas.add(d);
                    break;
                }
            }
        }
        return selecionadas;
    }
    public String atualizar(String antiga, String nova)
    {
        boolean EncontrouAntiga = false;

        if (collator.compare(antiga, nova) == 0)
        {
            for (String d : lista)
            {
                if (collator.compare(d, antiga) == 0)
                {
                    lista.remove(d);
                    lista.add(nova);
                    return "Atualização ocorrida com sucesso";
                }
            }
            return "A palavra '" + antiga + "' não foi encontrada";
        }
        else
        {
            for (String d : lista)
            {
                if (collator.compare(d, antiga) == 0)
                {
                    EncontrouAntiga = true;
                }
                if (collator.compare(d, nova) == 0)
                {
                    return "A palavra '" + nova + "' já existe";
                }
            }


            if (EncontrouAntiga)
            {
                lista.remove(antiga);
                lista.add(nova);
                return "Atualização ocorrida com sucesso!";
            }
            else
            {
                return "A palavra '" + antiga + "' não foi encontrada";
            }
        }
    }

    public String inserir(String palavra)
    {
        for (String d : lista)
        {
            if (collator.compare(d, palavra) == 0)
            {
                return "A palavra '" + palavra + "' já existe";
            }
        }
        lista.add(palavra);
        return "Palavra inserida com sucesso!";
    }

    public String excluir(String palavra)
    {
        for (String d : lista)
        {
            if (collator.compare(d, palavra) == 0)
            {
                lista.remove(palavra);
                return "Palavra excluida com sucesso!";
            }
        }
        return "A palavra '" + palavra + "' não foi encontrada";
    }
}

Main:


import java.util.logging.Level;
import java.util.logging.Logger;

public class Main
{

    public static void main(String[] args)
    {

        FilmesBu filmes = new FilmesBu();

        System.out.println( filmes.inserir("abcde") );
        System.out.println( filmes.inserir("bcdef") );
        System.out.println( filmes.inserir("cdefg") );
        System.out.println( filmes.inserir("defgHij") );
        System.out.println( filmes.inserir("ghi") );
        System.out.println( filmes.inserir("aBcde") );

        System.out.println(filmes.selecionar("ghí"));

        System.out.println(filmes.atualizar("abcde", "bcdef"));
        System.out.println(filmes.atualizar("abdcde", "Abscde"));
        System.out.println(filmes.atualizar("abcde", "Abscde"));

        System.out.println(filmes.excluir("gchi"));
        System.out.println(filmes.excluir("ghi"));

        System.out.println(filmes.selecionar(""));

    }
}

isso imprime:

Palavra inserida com sucesso!
Palavra inserida com sucesso!
Palavra inserida com sucesso!
Palavra inserida com sucesso!
Palavra inserida com sucesso!
A palavra ‘aBcde’ já existe
[defgHij, ghi]
A palavra ‘bcdef’ já existe
A palavra ‘abdcde’ não foi encontrada
Atualização ocorrida com sucesso!
A palavra ‘gchi’ não foi encontrada
Palavra excluida com sucesso!
[Abscde, bcdef, cdefg, defgHij]

A especificação de expressões regulares permite, no máximo, remover a diferença entre minúsculas e maiúsculas.

http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html#CASE_INSENSITIVE

Se sua lista for ordenada, pode tentar usar o Binary Search para usar o Collator:

http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#binarySearch(java.util.List,%20T,%20java.util.Comparator)

Senão, vai ter de procurar com um “for” mesmo :frowning:

[quote=entanglement]A especificação de expressões regulares permite, no máximo, remover a diferença entre minúsculas e maiúsculas.

http://docs.oracle.com/javase/6/docs/api/java/util/regex/Pattern.html#CASE_INSENSITIVE

Se sua lista for ordenada, pode tentar usar o Binary Search para usar o Collator:

http://docs.oracle.com/javase/6/docs/api/java/util/Collections.html#binarySearch(java.util.List,%20T,%20java.util.Comparator)

Senão, vai ter de procurar com um “for” mesmo :frowning:
[/quote]

Muito obrigado entanglement e ViniGodoy.