2010-04-21 17 views
21

J'ai écrit ce morceau de code qui divise une chaîne et la stocke dans un tableau de chaînes: -Éclate une chaîne en phrases

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

Cependant, j'ai ajouté le [az] parce que je voulais traiter une partie du problème d'abréviation. Mais mon résultat apparaît comme si: -

De plus, lorsque Everett a essayé de les instruire en mathématiques de base elles se sont avérées unresponsiv

Je vois que je perds le motif spécifié dans la fonction split. Je peux perdre la période, mais perdre la dernière lettre du mot perturbe sa signification.

Quelqu'un pourrait m'aider avec cela, et en outre, quelqu'un pourrait m'aider à traiter avec des abréviations? Par exemple, parce que je divise la chaîne en fonction des périodes, je ne veux pas perdre les abréviations.

Répondre

45

L'analyse de phrases est loin d'être une tâche triviale, même pour les langues latines comme l'anglais. Une approche naïve comme celle que vous avez esquissée dans votre question échouera assez souvent pour que cela se révèle inutile dans la pratique.

Une meilleure approche consiste à utiliser un BreakIterator configuré avec les paramètres régionaux appropriés.

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)); 
} 

donne le résultat suivant:

  1. Ceci est un test.
  2. Ceci est un T.L.A. tester.
  3. Maintenant avec un Dr. en elle.
+6

Lorsque j'utilise cette phrase - "Mon ami, M. Jones, a un nouveau chien." Il rompt après M. Il arrive à cause de la capitalisation de Jones. Connaissez-vous un moyen de contourner cela? Sinon, le BreakIterator est génial! – nbz

11

Il sera difficile d'obtenir une expression régulière pour travailler dans tous les cas, mais pour résoudre votre problème immédiat, vous pouvez utiliser un lookbehind:

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

Résultat:

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

Notez qu'il existe sont des abréviations qui ne se terminent pas par des majuscules, comme abbrev., Mr., etc ... Et il y a aussi des phrases qui ne se terminent pas en périodes!

+0

Merci pour votre réponse. –

+1

Cela échouera dans 9,3% des phrases. Et des phrases qui ... utilisent des ellipses. Et des phrases avec des typo.s en eux. Etc. Quoi que vous fassiez, votre code fera des erreurs, vu du point de vue humain. –

4

Si vous le pouvez, utilisez un outil de traitement du langage naturel, tel que LingPipe. Il y a beaucoup de subtilités qui seront très difficiles à attraper en utilisant des expressions régulières, par exemple, (par exemple :-)), M., abréviations, points de suspension (...), et ainsi de suite .

Il est très facile de suivre le tutoriel sur Sentence Detection sur le site Web de LingPipe.

+0

Salut, j'ai vérifié le tutoriel. Cela semblait parfait, mais je n'arrive pas à comprendre comment l'utiliser avec Eclipse.Pourriez-vous m'aider s'il vous plait? –