148 votes

Comment diviser un texte en phrases ?

J'ai un fichier texte. J'ai besoin d'obtenir une liste de phrases.

Comment cela peut-il être mis en œuvre ? Il y a beaucoup de subtilités, comme l'utilisation d'un point dans les abréviations.

Mon ancienne expression régulière fonctionne mal :

re.compile('(\. |^|!|\?)([A-Z][^;\.<>@\^&/\[\]]*(\.|!|\?) )',re.M)

0 votes

Je veux faire cela, mais je veux séparer chaque fois qu'il y a un point ou un saut de ligne.

8voto

woody Points 408

Vous pouvez également utiliser la fonction de tokenisation des phrases dans NLTK :

from nltk.tokenize import sent_tokenize
sentence = "As the most quoted English writer Shakespeare has more than his share of famous quotes.  Some Shakespare famous quotes are known for their beauty, some for their everyday truths and some for their wisdom. We often talk about Shakespeare’s quotes as things the wise Bard is saying to us but, we should remember that some of his wisest words are spoken by his biggest fools. For example, both ‘neither a borrower nor a lender be,’ and ‘to thine own self be true’ are from the foolish, garrulous and quite disreputable Polonius in Hamlet."

sent_tokenize(sentence)

8voto

Rafe Kettler Points 29389

Pour les cas simples (où les phrases se terminent normalement), cela devrait fonctionner :

import re
text = ''.join(open('somefile.txt').readlines())
sentences = re.split(r' *[\.\?!][\'"\)\]]* *', text)

La regex est *\. + qui correspond à un point entouré de 0 espace ou plus à gauche et de 1 espace ou plus à droite (pour éviter que quelque chose comme le point dans re.split soit compté comme un changement de phrase).

Évidemment, ce n'est pas la solution la plus robuste, mais elle fera l'affaire dans la plupart des cas. Le seul cas qui n'est pas couvert est celui des abréviations (vous pouvez parcourir la liste des phrases et vérifier que chaque chaîne de caractères dans le champ sentences commence par une majuscule ?)

34 votes

Vous ne pouvez pas penser à une situation en anglais où une phrase ne se termine pas par un point ? Imaginez ça ! Ma réponse à cela serait, "réfléchissez encore". (Vous voyez ce que j'ai fait là ?)

0 votes

Ned wow, je ne peux pas croire que j'ai été aussi stupide. Je dois être bourré ou quelque chose comme ça.

0 votes

J'utilise Python 2.7.2 sur Win 7 x86, et le regex dans le code ci-dessus me donne cette erreur : SyntaxError: EOL while scanning string literal en pointant vers la parenthèse fermante (après text ). De plus, la regex à laquelle vous faites référence dans votre texte n'existe pas dans votre exemple de code.

4voto

Gucci148 Points 1189

Utilisation de spacy :

import spacy

nlp = spacy.load('en_core_web_sm')
text = "How are you today? I hope you have a great day"
tokens = nlp(text)
for sent in tokens.sents:
    print(sent.string.strip())

2voto

TefoD Points 67

Si le sent_tokenize de NLTK n'est pas une chose (par exemple, il nécessite beaucoup de mémoire vive du GPU pour les textes longs) et si le regex ne fonctionne pas correctement dans toutes les langues, séparateur de phrases pourrait valoir la peine d'être essayé.

2voto

Vous pourriez créer un nouveau tokenizer pour le russe (et d'autres langues) en utilisant cette fonction :

def russianTokenizer(text):
    result = text
    result = result.replace('.', ' . ')
    result = result.replace(' .  .  . ', ' ... ')
    result = result.replace(',', ' , ')
    result = result.replace(':', ' : ')
    result = result.replace(';', ' ; ')
    result = result.replace('!', ' ! ')
    result = result.replace('?', ' ? ')
    result = result.replace('\"', ' \" ')
    result = result.replace('\'', ' \' ')
    result = result.replace('(', ' ( ')
    result = result.replace(')', ' ) ') 
    result = result.replace('  ', ' ')
    result = result.replace('  ', ' ')
    result = result.replace('  ', ' ')
    result = result.replace('  ', ' ')
    result = result.strip()
    result = result.split(' ')
    return result

et l'appeler de cette façon :

text = '  ,  Google SSL;'
tokens = russianTokenizer(text)

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X