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’”.
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());
}
}
}
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 ) e um loop com um switch monstruoso … Meio porco mas funciona.
Gostei do exemplo, entendi como funciona esse aspecto
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