2010-04-21 21 views
21

Ho scritto questo pezzo di codice che divide una stringa e lo memorizza in un array di stringhe: -stringa di Split in frasi

String[] sSentence = sResult.split("[a-z]\\.\\s+"); 

Tuttavia, ho aggiunto il [az] perché volevo affrontare alcuni dei problemi di abbreviazione. Ma poi il mio risultato mostra come così: -

Inoltre quando Everett ha cercato di istruirli nella matematica di base hanno dimostrato unresponsiv

vedo che perdo il criterio specificato nella funzione split. Va bene per me perdere il periodo, ma perdere l'ultima lettera della parola disturba il suo significato.

Qualcuno potrebbe aiutarmi con questo, e inoltre, qualcuno potrebbe aiutarmi a trattare con le abbreviazioni? Ad esempio, poiché divido la stringa in base ai periodi, non voglio perdere le abbreviazioni.

risposta

45

Le frasi di analisi sono lungi dall'essere un compito banale, anche per le lingue latine come l'inglese. Un approccio ingenuo come quello che esponi nella tua domanda fallirà abbastanza spesso da renderlo inutilizzabile nella pratica.

Un approccio migliore consiste nell'utilizzare un BreakIterator configurato con le impostazioni internazionali corrette.

BreakIterator iterator = BreakIterator.getSentenceInstance(Locale.US); 
String source = "This is a test. This is a T.L.A. test. Now with a Dr. in it."; 
iterator.setText(source); 
int start = iterator.first(); 
for (int end = iterator.next(); 
    end != BreakIterator.DONE; 
    start = end, end = iterator.next()) { 
    System.out.println(source.substring(start,end)); 
} 

produce il seguente risultato:

  1. Questo è un test.
  2. Questo è un T.L.A. test.
  3. Ora con un Dott. In esso.
+6

Quando uso questa frase: "Il mio amico, Mr. Jones, ha un nuovo cane". Si rompe dopo che Mr. sta accadendo a causa della capitalizzazione di Jones. Conosci un modo per aggirarlo? Altrimenti BreakIterator è fantastico! – nbz

11

Sarà difficile ottenere un'espressione regolare per lavorare in tutti i casi, ma per risolvere il problema immediato è possibile utilizzare una lookbehind:

String sResult = "This is a test. This is a T.L.A. test."; 
String[] sSentence = sResult.split("(?<=[a-z])\\.\\s+"); 

Risultato:

This is a test 
This is a T.L.A. test. 

noti che ci sono abbreviazioni che non finiscono con lettere maiuscole, come abbrev., Mr., ecc ... E ci sono anche frasi che non finiscono in periodi!

+0

Grazie per la risposta. –

+1

Questo fallirà nel 9,3% delle frasi. E frasi che ... usano l'ellissi. E frasi con errori di battitura in loro. E così via. Qualunque cosa tu faccia, il tuo codice commetterà errori, visti dalla prospettiva umana. –

4

Se possibile, utilizzare uno strumento di elaborazione del linguaggio naturale, ad esempio LingPipe. Ci sono molte sottigliezze che sarà molto difficile da catturare utilizzando le espressioni regolari, per esempio, (per esempio :-)), signor, abbreviazioni, puntini di sospensione (...), eccetera.

Esiste un tutorial molto semplice da seguire su Sentence Detection nel sito Web di LingPipe.

+0

Ciao, ho controllato il tutorial. Sembrava perfetto, tuttavia non riesco a capire come usarlo con Eclipse.Potresti aiutarmi, per favore? –