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.

1voto

cogijl Points 31

Méfiez-vous également des domaines de premier niveau supplémentaires qui ne figurent pas dans certaines des réponses ci-dessus.

Par exemple, les noms .info, .biz, .ru, .online sont susceptibles d'être utilisés par certains analyseurs de phrases, mais ne sont pas inclus ci-dessus.

Voici quelques informations sur la fréquence des domaines de premier niveau : https://www.westhost.com/blog/the-most-popular-top-level-domains-in-2017/

Cela peut être résolu en modifiant le code ci-dessus comme suit :

alphabets= "([A-Za-z])"
prefixes = "(Mr|St|Mrs|Ms|Dr)[.]"
suffixes = "(Inc|Ltd|Jr|Sr|Co)"
starters = "(Mr|Mrs|Ms|Dr|He\s|She\s|It\s|They\s|Their\s|Our\s|We\s|But\s|However\s|That\s|This\s|Wherever)"
acronyms = "([A-Z][.][A-Z][.](?:[A-Z][.])?)"
websites = "[.](com|net|org|io|gov|ai|edu|co.uk|ru|info|biz|online)"

0 votes

Cette information est utile, mais il serait peut-être plus approprié de l'ajouter sous la forme d'un bref commentaire sur la réponse originale.

1 votes

C'était mon plan initial, mais je n'ai pas encore la réputation pour ça apparemment. J'ai pensé que cela pourrait aider quelqu'un, alors j'ai pensé le poster du mieux que je pouvais. S'il y a un moyen de le faire et de contourner le "il faut d'abord avoir 50 de réputation", j'en serais ravi :)

1voto

biop Points 25

Autant le dire tout de suite, puisque c'est le premier message qui s'affiche pour la division de la phrase par n phrases.

Cela fonctionne avec une longueur de division variable, qui indique les phrases qui sont réunies à la fin.

import nltk
//nltk.download('punkt')
from more_itertools import windowed

split_length = 3 // 3 sentences for example 

elements = nltk.tokenize.sent_tokenize(text)
segments = windowed(elements, n=split_length, step=split_length)
text_splits = []
for seg in segments:
          txt = " ".join([t for t in seg if t])
          if len(txt) > 0:
                text_splits.append(txt)

1voto

vaichidrewar Points 2154

Il ne fait aucun doute que NLTK est le plus adapté à cet objectif. Mais le démarrage avec NLTK est assez pénible (mais une fois que vous l'avez installé, vous en récoltez les fruits).

Voici donc un code simple basé sur le re disponible à http://pythonicprose.blogspot.com/2009/09/python-split-paragraph-into-sentences.html

# split up a paragraph into sentences
# using regular expressions

def splitParagraphIntoSentences(paragraph):
    ''' break a paragraph into sentences
        and return a list '''
    import re
    # to split by multile characters

    #   regular expressions are easiest (and fastest)
    sentenceEnders = re.compile('[.!?]')
    sentenceList = sentenceEnders.split(paragraph)
    return sentenceList

if __name__ == '__main__':
    p = """This is a sentence.  This is an excited sentence! And do you think this is a question?"""

    sentences = splitParagraphIntoSentences(p)
    for s in sentences:
        print s.strip()

#output:
#   This is a sentence
#   This is an excited sentence

#   And do you think this is a question

3 votes

Yey mais ça échoue si facilement, avec : "M. Smith sait que c'est une phrase."

0voto

kishore Points 66

Je devais lire des fichiers de sous-titres et les découper en phrases. Après un prétraitement (comme la suppression des informations temporelles, etc. dans les fichiers .srt), la variable fullFile contenait le texte complet du fichier de sous-titres. La méthode brute ci-dessous permet de les diviser en phrases. J'ai probablement eu la chance que les phrases se terminent toujours (correctement) par un espace. Essayez d'abord cette méthode et si elle présente des exceptions, ajoutez des contrôles supplémentaires.

# Very approximate way to split the text into sentences - Break after ? . and !
fullFile = re.sub("(\!|\?|\.) ","\\1<BRK>",fullFile)
sentences = fullFile.split("<BRK>");
sentFile = open("./sentences.out", "w+");
for line in sentences:
    sentFile.write (line);
    sentFile.write ("\n");
sentFile.close;

Oh ! bien. Je réalise maintenant que puisque mon contenu était espagnol, je n'ai pas eu à faire face aux problèmes de "M. Smith", etc. Néanmoins, si quelqu'un veut un analyseur rapide et sale...

0voto

mamtimen Points 1

J'espère que cela vous aidera pour les textes latins, chinois et arabes.

import re

punctuation = re.compile(r"([^\d+])(\.|!|\?|;|\n|。|!|?|;|…| |!|؟|؛)+")
lines = []

with open('myData.txt','r',encoding="utf-8") as myFile:
    lines = punctuation.sub(r"\1\2<pad>", myFile.read())
    lines = [line.strip() for line in lines.split("<pad>") if line.strip()]

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