Preciso mapear os tokens (palavras) de dada frase para um array de String mas não sei como utilizar uma regexp correta para splitar corretamente para o array. Do jeito que fiz, ele pega o espaço em branco pós-separadores (vírgulas, dois-pontos e afins) e considera como um token também. Fiz uma “gambiarra” para corrigir.
Fiz o seguinte:
public class MapeadoraFrase {
private static final String REGEX = "\\,|\\;|\\:|\\.|\\?|\\!|\\ ";
private String frase;
private String[] tokens;
private Map<Integer, Character> separadores;
public MapeadoraFrase(String frase) {
tokens = frase.split(REGEX);
for (int i=0; i < tokens.length; i++)
tokens[i] = tokens[i].replaceAll(" ", "");
}
public void exibirTokens() {
for (int i = 0; i < tokens.length; i++)
Main.print(String.format("[%d] \'%s\'", i, tokens[i]));
}
}
Classe do main:
[code]public class Main {
/**
* @param args
*/
public static void main(String[] args) {
new MapeadoraFrase("Esta, é uma frase: a ser tokenizada.").exibirTokens();
}
public static void print(Object obj) {
System.out.println(obj);
}
}
[/code]
Note que, ao comentar o “FOR” do construtor os espaços em branco são considerados como palavras e vão para o array. Como filtro isso sem gambiarras?
Grato desde já.
Mude a regex.
Eu escreveria sua regex como:
"[ ,;:.?!]+"
Obrigado pela resposta. E outra pergunta: como splitar um texto em frases? Como dá pra ver, não sei nada de regex.
Grato.
O que é uma frase para você?
- É algo que termina em um ponto final, ou um ponto de interrogação, ou um ponto de exclamação. O único problema é que abreviaturas, como “sr. Junqueira”, teriam que ser identificadas para não terminar indevidamente uma frase.
- Não se esqueça que na história dos pontos, você tem de considerar as devidas combinações dos pontos. Por exemplo:
Era uma vez… Você é do tempo em que os animais falavam!!!
Ou seja, provavelmente sua expressão regular será algo como:
"[.!?]+"
Como se vê, mais importante que saber regex, é saber definir o problema. Mesmo um problema aparentemente simples como “separar um texto em frases” é na verdade algo que deve ser bem definido, e talvez acabe sendo mais complicado que parece, e não seja fácil de resolver só com expressões regulares. Por exemplo, a expressão regular que lhe passei não cuida do caso das abreviaturas, o que irá causar problemas.
Só para ter uma ideia, se você usar as expressões regulares e split para separar as frases, você perderá os pontos
Por exemplo, naquele exemplo que lhe passei:
"Era uma vez… Você é do tempo em que os animais falavam!!! "
Você teria o seguinte array de strings:
“Era uma vez”
" Você é do tempo em que os animais falavam"
" "
Ou seja, você perde os pontos 
É melhor usar Pattern, Matcher e os métodos find e group da classe Matcher, assim não perderá os pontos, entretanto dá um pouco mais de trabalho.