Problemas com regexp

Oi pessoal, boa tarde.

Dada a String:
“É MAIOR QUE 1 AND É MENOR QUE 3 OR COMEÇA COM ‘asd’”

Preciso separar em arrays distintos as funções (É MAIOR QUE, É MENOR QUE, COMEÇA COM), os valores (1, 3, ‘asd’) e os operadores (AND, OR).

Sendo que:

  • os nomes das funções são constantes
  • os nomes dos operadores são constantes
  • a quantidade de operadores e funções não é constante

Isso aqui:
String[] values = text.split( “[É MAIOR QUE]|[É MENOR QUE]|[COMEÇA COM]|[OR]|[AND]” );

Me retorna um array com 45 posições, sendo apenas 3 os valores da expressão e o resto null. Até ai tudo bem.

Mas estou apanhando um bocado para retirar o resto.
Alguém pode ajudar?

Valeu povo!

Criar um array auxiliar, e setar os seus arrays que nao sao null, no array auxiliar, seria uma solucao? :roll:

Não entendi cara :smiley:

Update by TedAloprao:
String[] values = text.split( “É MAIOR QUE|É MENOR QUE|COMEÇA COM|OR|AND” );

retorna um array com 6 posições, 3 nulas.

Mas ainda estou apanhando ferozmente para as funções e os operadores. Preciso fazer algo que negue um literal. Por exemplo para os operadores: “retirar todas as palavras que NÃO são ‘OR’ ou ‘AND’”.

O mesmo para funções.

Se tem uma coisa para a qual expressões regulares não são indicadas é para implementar coisas que são melhor expressas por gramáticas tradicionais - imagine qual o trabalho que daria se alguém fosse tentar implementar um compilador Java (cuja gramática, até a versão 1.4, é relativamente simples) só com expressões regulares, ou mesmo um interpretador SQL.
Acho que um dos casos clássicos é o de tentar avaliar uma expressão aritmética com parênteses. É meio complicado fazer isso só com expressões regulares.
Em defesa das expressões regulares, existem muitos dados que podem ser perfeitamente interpretados só com expressões regulares (veja o sucesso da linguagem Perl).
Ah, e esse negócio de negar em expressões regulares não é imediato - uma vez neste forum foi perguntado como é que se fazia isso. Aqui tem um exemplo de como verificar se uma string NÃO começa com “boca”. (Não é o caso de NÃO ter uma “boca” no meio.)

import java.util.regex.*;
import java.util.*;

class LookBehind {
    public static void main(String[] args) {
        String[] test = {
            "Boca Ratón",
            "tem boca livre no Bar Batana hoje",
            "bocca",
            "qualquer coisa",
        };
        Pattern pat = Pattern.compile("(?!boca).*", Pattern.CASE_INSENSITIVE);
        for (int i = 0; i < test.length; ++i) {
            System .out .println ("<" + test[i] + "> : " + pat.matcher(test[i]).matches());
        }
    }
}

Ok thingol, mas tenho certeza que para este caso simplérrimo regexps devem funcionar melhor do que quilos de substrings e indexOfs hehe

Ainda mais que a sintaxe das expressões será sempre essa:
FUNCAO VALOR OPERADOR FUNCAO VALOR OPERADOR FUNCAO VALOR.

Só um adendo

:XD:

No seu caso em particular, onde a gramática é (como você disse) simplérrima, mais um motivo para usar java.io.StreamTokenizer (não é StringTokenizer, não confunda o “Qual é a Música” do Sílvio Santos com o “Show da Música” do Tom Cavalcante :wink: ) e um loop com um switch monstruoso … Meio porco mas funciona.

hehe thingol, como acabei de falar para o Shoes, sei que consigo realizar essa tarefa com SPCSPL*, mas … mas … com regexp fica tão bonitinho :smiley:

[size=8]* SPCSPL = String Pra Ca String Pra La - cv[/size]

Bom, leia o tópico que editei onde eu tento ver se a frase não começa com “boca”. Essa expressão regular “(?!boca)” é engraçada, veja se lhe ajuda.

Gostei do exemplo, entendi como funciona esse aspecto :smiley:

Bom, consegui resolver de um jeito mais simples:

String text = "É MAIOR QUE 1 AND É MENOR QUE 3 OR COMEÇA COM 'asd'";
String[] values = text.split( "É MAIOR QUE|É MENOR QUE|COMEÇA COM|OR|AND" );
text = clearAlreadyFound( text, values );
String[] functions = text.split( "AND| OR" );
text = clearAlreadyFound( text, functions );
String[] operators = text.split( " " );

o método clearAlreadyFound( String exp, String[] valuesToRemove ) remove da String básica os valores já encontrados :smiley:

Obrigado pessoal :smiley: