Procurar texto em string com asterisco

Primeiramente, não gostaria de usar expressão regular. Já pesquisei no google em português e inglês e não encontrei nada.

Queria saber se vocês tem alguma coisa pronta para o problema que estou enfrentando, se ninguém tiver, eu vou implementar e depois eu posto o método aqui para todos.

Seguinte… Existe uma string que é digitada pelo usuário (busca), e existe o nome de várias classes na variavel texto, dentro de um loop. Quero um método que compare strings mas que se tiver asterisco no começo, meio ou fim, isso seja levado em consideração. Resumindo: Uma comparação de strings com asterisco.

String busca = “Converter*Handler”;
String texto = “ConverterConfigNamespaceHandler”;

if( metodoDeComparacaoComAsterisco(busca, texto) )
{
// EXISTE...
}

Valeu!

Você pode converter sua expressão de busca para uma expressão regular, e usar essa expressão regular :slight_smile:

Seu tipo de busca é apenas com “*” ou você também quer uma com “?” (como se fosse para achar nomes de arquivos)?

[quote=entanglement]Você pode converter sua expressão de busca para uma expressão regular, e usar essa expressão regular :slight_smile:

Seu tipo de busca é apenas com “*” ou você também quer uma com “?” (como se fosse para achar nomes de arquivos)?
[/quote]

Eu tentei fazer isso substituindo os asteriscos por ponto e asterisco, porém expressão regular funciona como um “contains” e ele acaba encontrando mais do que devia…

Por exemplo:

String busca = “Converter*Namespace”;

isso se tornaria “Converter.*Namespace”;

não é para encontrar a string “ConverterConfigNamespaceHandler” porém ele acaba encontrando, entendeu?

A não ser que tenha algo em expressão regular que delimite o início e o fim.

String busca = "Converter.*Handler";
String texto = "ConverterConfigNamespaceHandler"; 
...
if (texto.matches (busca)) {
    ...
}

Provavelmente você usou “find”, não “matches”.

[quote=entanglement] String busca = "Converter.*Handler"; String texto = "ConverterConfigNamespaceHandler"; ... if (texto.matches (busca)) { ... }

Provavelmente você usou “find”, não “matches”. [/quote]

Olá, isso não funciona pois como eu disse ali em cima, se a busca for “Converter.*Namespace” ainda assim ele encontra aquela ali, pois a expressão regular trabalha como se fosse “contains”…

Dica, aloha-san:

Aprenda expressões regulares. No começo é complicado, mas vai lhe ajudar a resolver muitos problemas.

Só uma coisinha. Você vai ver, com o tempo, que:

a) Nem sempre você consegue criar uma expressão regular que resolve seu problema.
Muitas vezes você precisa usar pelo menos duas: uma que bate com o que você quer achar, e outra que bate com o que você não quer usar.
É que é bem mais difícil criar uma expressão regular que NÃO bata com alguma coisa, que algo que bata com alguma coisa.
O uso do “(?!)” e outras expressões regulares esquisitas (conhecidas como “negative lookahead” ou “negative lookbehind”) não é muito recomendado, justamente porque é muito frágil e difícil de usar direito.

[quote=aloha][quote=entanglement] String busca = "Converter.*Handler"; String texto = "ConverterConfigNamespaceHandler"; ... if (texto.matches (busca)) { ... }

Provavelmente você usou “find”, não “matches”. [/quote]

Olá, isso não funciona pois como eu disse ali em cima, se a busca for “Converter.*Namespace” ainda assim ele encontra aquela ali, pois a expressão regular trabalha como se fosse “contains”…[/quote]

Tem certeza? Experimente de novo. É “matches”, não “find”. Confira seu programa :slight_smile:

De qualquer forma, o início e o fim são respectivamente “^” e “$”. Um exemplo:

String busca = "^Converter.*Namespace$";  
String texto = "ConverterConfigNamespaceHandler";   
...  
Pattern pat = Pattern.compile (busca, Pattern.IGNORE_CASE);
if (pat.matcher (texto).find()) {
    ...

[quote=entanglement]Dica, aloha-san:

Aprenda expressões regulares. No começo é complicado, mas vai lhe ajudar a resolver muitos problemas.

Só uma coisinha. Você vai ver, com o tempo, que:

a) Nem sempre você consegue criar uma expressão regular que resolve seu problema.
Muitas vezes você precisa usar pelo menos duas: uma que bate com o que você quer achar, e outra que bate com o que você não quer usar.
É que é bem mais difícil criar uma expressão regular que NÃO bata com alguma coisa, que algo que bata com alguma coisa.
O uso do “(?!)” e outras expressões regulares esquisitas (conhecidas como “negative lookahead” ou “negative lookbehind”) não é muito recomendado, justamente porque é muito frágil e difícil de usar direito. [/quote]

Dae cara beleza? Então o problema é que a única coisa que vou usar de expressão regular nisso seria o asterisco, daí teria que fazer um monte de coisa para não usar as outras coisas…

Se quiser outra alternativa, tem o StringUtils do apache-lang. Ele faz tudo o que se imagina com Strings.

[quote=entanglement]De qualquer forma, o início e o fim são respectivamente “^” e “$”. Um exemplo:

String busca = "^Converter.*Namespace$"; String texto = "ConverterConfigNamespaceHandler"; ... Pattern pat = Pattern.compile (busca, Pattern.IGNORE_CASE); if (pat.matcher (texto).find()) { ... [/quote]

Simplesmente perfeito. Testado e aprovado! Obrigado entanglement e a todos que ajudaram.

package guj;

import java.util.regex.Matcher;
import java.util.regex.Pattern;

class ProcurarComAsterisco {
    /**
     * Configurar a busca (isso é importante para acelerar a busca). 
     * @param busca O padrão a ser buscado. O único caracter especial é "*", que será equivalente a ".*"
     */
    public void configurarBusca (String busca) {
        String padraoModificado;
        // Devemos escapar todos os caracteres que são especiais para padrões, exceto "*", que será trocado por ".*"
        padraoModificado = busca.replaceAll("([.\\?|+()\\[\\]])", "\\\\$1").replaceAll("\\*", ".*");
        padrao = Pattern.compile (padraoModificado);
    }
    /** 
     * Bate a string inteira com o padrão.
     * @param string A string onde procurar o padrão
     * @return true se bater, false se não bater
     */
    public boolean bater (String string) {
        return padrao.matcher (string).matches();
    }
    /**
     * Procura o padrão na string.
     * @param string A string onde procurar o padrão
     * @return -1 se não achar, a posição inicial (0 ... string.length-1) se achar. 
     */
    public int achar (String string) {
        Matcher matcher = padrao.matcher (string);
        if (matcher.find())
            return matcher.start();
        else
            return -1;
    }
    private Pattern padrao;
}

public class ExemploProcurarComAsterisco {

    
    
    /**
     * @param args
     */
    public static void main(String[] args) {
        ProcurarComAsterisco pca = new ProcurarComAsterisco ();
        pca.configurarBusca("Converter*Namespace");
        System.out.println (pca.bater ("ConverterConfigNamespaceHandler")); // false
        System.out.println (pca.bater ("ConverterConfigNamespace")); // true
        pca.configurarBusca("Hand*");
        System.out.println (pca.achar ("ConverterConfigNamespaceHandler")); // 24
        System.out.println (pca.achar ("ConverterConfigNamespace")); // -1
        pca.configurarBusca("*.*");
        System.out.println (pca.bater ("2.13")); // true
        System.out.println (pca.bater ("213")); // false
        pca.configurarBusca("[*]");
        System.out.println (pca.bater ("Dilbert")); // false
        System.out.println (pca.bater ("[Dilbert]")); // true
    }

}