ฉันมีไฟล์ข้อความ ฉันต้องการรายชื่อประโยค
วิธีนี้สามารถนำไปใช้? มีรายละเอียดปลีกย่อยมากมายเช่นจุดที่ใช้ในตัวย่อ
นิพจน์ทั่วไปเก่าของฉันทำงานได้ไม่ดี:
re.compile('(\. |^|!|\?)([A-Z][^;↑\.<>@\^&/\[\]]*(\.|!|\?) )',re.M)
ฉันมีไฟล์ข้อความ ฉันต้องการรายชื่อประโยค
วิธีนี้สามารถนำไปใช้? มีรายละเอียดปลีกย่อยมากมายเช่นจุดที่ใช้ในตัวย่อ
นิพจน์ทั่วไปเก่าของฉันทำงานได้ไม่ดี:
re.compile('(\. |^|!|\?)([A-Z][^;↑\.<>@\^&/\[\]]*(\.|!|\?) )',re.M)
คำตอบ:
Natural Language Toolkit ( nltk.org ) มีสิ่งที่คุณต้องการ การโพสต์กลุ่มนี้บ่งชี้ว่าสิ่งนี้ทำได้:
import nltk.data
tokenizer = nltk.data.load('tokenizers/punkt/english.pickle')
fp = open("test.txt")
data = fp.read()
print '\n-----\n'.join(tokenizer.tokenize(data))
(ยังไม่ได้ลอง!)
nltk .tokenize.punkt.PunktSentenceTokenizer
นี่คือการเชื่อมโยงโดยตรงกับเอกสารออนไลน์
nltk.download()
ก่อนและดาวน์โหลดโมเดล ->punkt
'This fails on cases with ending quotation marks. If we have a sentence that ends like "this." This is another sentence.'
และผลลัพธ์ของฉัน['This fails on cases with ending quotation marks.', 'If we have a sentence that ends like "this."', 'This is another sentence.']
ดูเหมือนว่าถูกต้องสำหรับฉัน
ฟังก์ชั่นนี้สามารถแบ่งข้อความทั้งหมดของ Huckleberry Finn ออกเป็นประโยคได้ภายในเวลาประมาณ 0.1 วินาทีและจัดการกับหลาย ๆ กรณีที่เจ็บปวดมากขึ้นซึ่งทำให้การแยกประโยคเป็นเรื่องไม่สำคัญเช่น " Mr.John Johnson Jr. เกิดในสหรัฐอเมริกา แต่ได้รับปริญญาเอก D. ในอิสราเอลก่อนจะร่วมงานกับ Nike Inc. ในตำแหน่งวิศวกรนอกจากนี้เขายังทำงานที่ Craigslist.org ในตำแหน่งนักวิเคราะห์ธุรกิจด้วย "
# -*- coding: utf-8 -*-
import re
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)"
def split_into_sentences(text):
text = " " + text + " "
text = text.replace("\n"," ")
text = re.sub(prefixes,"\\1<prd>",text)
text = re.sub(websites,"<prd>\\1",text)
if "Ph.D" in text: text = text.replace("Ph.D.","Ph<prd>D<prd>")
text = re.sub("\s" + alphabets + "[.] "," \\1<prd> ",text)
text = re.sub(acronyms+" "+starters,"\\1<stop> \\2",text)
text = re.sub(alphabets + "[.]" + alphabets + "[.]" + alphabets + "[.]","\\1<prd>\\2<prd>\\3<prd>",text)
text = re.sub(alphabets + "[.]" + alphabets + "[.]","\\1<prd>\\2<prd>",text)
text = re.sub(" "+suffixes+"[.] "+starters," \\1<stop> \\2",text)
text = re.sub(" "+suffixes+"[.]"," \\1<prd>",text)
text = re.sub(" " + alphabets + "[.]"," \\1<prd>",text)
if "”" in text: text = text.replace(".”","”.")
if "\"" in text: text = text.replace(".\"","\".")
if "!" in text: text = text.replace("!\"","\"!")
if "?" in text: text = text.replace("?\"","\"?")
text = text.replace(".",".<stop>")
text = text.replace("?","?<stop>")
text = text.replace("!","!<stop>")
text = text.replace("<prd>",".")
sentences = text.split("<stop>")
sentences = sentences[:-1]
sentences = [s.strip() for s in sentences]
return sentences
prefixes = "(Mr|St|Mrs|Ms|Dr|Prof|Capt|Cpt|Lt|Mt)[.]"
, websites = "[.](com|net|org|io|gov|me|edu)"
และif "..." in text: text = text.replace("...","<prd><prd><prd>")
แทนที่จะใช้ regex ในการแยกข้อความออกเป็นประโยคคุณยังสามารถใช้ nltk library
>>> from nltk import tokenize
>>> p = "Good morning Dr. Adams. The patient is waiting for you in room number 3."
>>> tokenize.sent_tokenize(p)
['Good morning Dr. Adams.', 'The patient is waiting for you in room number 3.']
for sentence in tokenize.sent_tokenize(text): print(sentence)
คุณสามารถลองใช้Spacyแทน regex ฉันใช้มันและได้ผล
import spacy
nlp = spacy.load('en')
text = '''Your text here'''
tokens = nlp(text)
for sent in tokens.sents:
print(sent.string.strip())
นี่คือแนวทางกลางทางที่ไม่ต้องพึ่งพาห้องสมุดภายนอกใด ๆ ฉันใช้การทำความเข้าใจรายการเพื่อยกเว้นการทับซ้อนระหว่างตัวย่อและตัวยุติรวมถึงยกเว้นการทับซ้อนระหว่างรูปแบบต่างๆของการยุติตัวอย่างเช่น "." เทียบกับ '. "'
abbreviations = {'dr.': 'doctor', 'mr.': 'mister', 'bro.': 'brother', 'bro': 'brother', 'mrs.': 'mistress', 'ms.': 'miss', 'jr.': 'junior', 'sr.': 'senior',
'i.e.': 'for example', 'e.g.': 'for example', 'vs.': 'versus'}
terminators = ['.', '!', '?']
wrappers = ['"', "'", ')', ']', '}']
def find_sentences(paragraph):
end = True
sentences = []
while end > -1:
end = find_sentence_end(paragraph)
if end > -1:
sentences.append(paragraph[end:].strip())
paragraph = paragraph[:end]
sentences.append(paragraph)
sentences.reverse()
return sentences
def find_sentence_end(paragraph):
[possible_endings, contraction_locations] = [[], []]
contractions = abbreviations.keys()
sentence_terminators = terminators + [terminator + wrapper for wrapper in wrappers for terminator in terminators]
for sentence_terminator in sentence_terminators:
t_indices = list(find_all(paragraph, sentence_terminator))
possible_endings.extend(([] if not len(t_indices) else [[i, len(sentence_terminator)] for i in t_indices]))
for contraction in contractions:
c_indices = list(find_all(paragraph, contraction))
contraction_locations.extend(([] if not len(c_indices) else [i + len(contraction) for i in c_indices]))
possible_endings = [pe for pe in possible_endings if pe[0] + pe[1] not in contraction_locations]
if len(paragraph) in [pe[0] + pe[1] for pe in possible_endings]:
max_end_start = max([pe[0] for pe in possible_endings])
possible_endings = [pe for pe in possible_endings if pe[0] != max_end_start]
possible_endings = [pe[0] + pe[1] for pe in possible_endings if sum(pe) > len(paragraph) or (sum(pe) < len(paragraph) and paragraph[sum(pe)] == ' ')]
end = (-1 if not len(possible_endings) else max(possible_endings))
return end
def find_all(a_str, sub):
start = 0
while True:
start = a_str.find(sub, start)
if start == -1:
return
yield start
start += len(sub)
ฉันใช้ฟังก์ชัน find_all ของ Karl จากรายการนี้: ค้นหาการเกิดขึ้นทั้งหมดของสตริงย่อยใน Python
...
?!
สำหรับกรณีง่ายๆ (โดยปกติประโยคจะถูกยกเลิก) สิ่งนี้ควรได้ผล:
import re
text = ''.join(open('somefile.txt').readlines())
sentences = re.split(r' *[\.\?!][\'"\)\]]* *', text)
นิพจน์ทั่วไปคือ*\. +
ซึ่งจับคู่กับจุดที่ล้อมรอบด้วยช่องว่าง 0 หรือมากกว่าทางด้านซ้ายและ 1 หรือมากกว่าทางด้านขวา (เพื่อป้องกันไม่ให้บางสิ่งเช่นจุดใน re.split ถูกนับเป็นการเปลี่ยนแปลงในประโยค)
เห็นได้ชัดว่าไม่ใช่วิธีแก้ปัญหาที่แข็งแกร่งที่สุด แต่ในกรณีส่วนใหญ่จะทำได้ดี กรณีเดียวที่จะไม่ครอบคลุมคือคำย่อ (อาจเรียกใช้ในรายการประโยคและตรวจสอบว่าแต่ละสตริงsentences
ขึ้นต้นด้วยอักษรตัวใหญ่หรือไม่)
SyntaxError: EOL while scanning string literal
ชี้ไปที่วงเล็บปิด (หลังtext
) นอกจากนี้นิพจน์ทั่วไปที่คุณอ้างอิงในข้อความของคุณไม่มีอยู่ในตัวอย่างโค้ดของคุณ
r' *[\.\?!][\'"\)\]]* +'
คุณยังสามารถใช้ฟังก์ชัน tokenization ประโยคใน 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)
@Artyom,
ไฮ! คุณสามารถสร้างโทเค็นใหม่สำหรับภาษารัสเซีย (และภาษาอื่น ๆ ) โดยใช้ฟังก์ชันนี้:
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
แล้วเรียกในลักษณะนี้:
text = 'вы выполняете поиск, используя Google SSL;'
tokens = russianTokenizer(text)
ขอให้โชคดี Marilena
ไม่ต้องสงสัยเลยว่า NLTK เหมาะสมที่สุดสำหรับวัตถุประสงค์ แต่การเริ่มต้นกับ NLTK นั้นค่อนข้างเจ็บปวด (แต่เมื่อคุณติดตั้งแล้วคุณก็จะได้รับรางวัล)
ดังนั้นนี่คือโค้ด re based ง่ายๆที่มีอยู่ที่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
ฉันต้องอ่านไฟล์คำบรรยายและแยกเป็นประโยค หลังจากการประมวลผลล่วงหน้า (เช่นการลบข้อมูลเวลา ฯลฯ ในไฟล์. srt) ตัวแปร fullFile จะมีข้อความเต็มของไฟล์คำบรรยาย วิธีหยาบด้านล่างแบ่งออกเป็นประโยคอย่างเรียบร้อย ฉันอาจจะโชคดีที่ประโยคนั้นลงท้ายด้วยการเว้นวรรค (อย่างถูกต้อง) เสมอ ลองใช้สิ่งนี้ก่อนและหากมีข้อยกเว้นให้เพิ่มการตรวจสอบและยอดคงเหลือเพิ่มเติม
# 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;
โอ้! ดี. ตอนนี้ฉันรู้แล้วว่าเนื่องจากเนื้อหาของฉันเป็นภาษาสเปนฉันจึงไม่มีปัญหาในการจัดการกับ "Mr. Smith" เป็นต้น แต่หากมีใครต้องการตัวแยกวิเคราะห์ที่รวดเร็วและสกปรก ...
ฉันหวังว่านี่จะช่วยคุณเกี่ยวกับข้อความภาษาละตินจีนและภาษาอาหรับ
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()]
กำลังทำงานในงานที่คล้ายกันและพบกับข้อความค้นหานี้โดยทำตามลิงก์ไม่กี่ลิงก์และทำงานกับแบบฝึกหัดบางส่วนสำหรับ nltk โค้ดด้านล่างนี้ใช้ได้ผลกับฉันเหมือนเวทมนตร์
from nltk.tokenize import sent_tokenize
text = "Hello everyone. Welcome to GeeksforGeeks. You are studying NLP article"
sent_tokenize(text)
เอาต์พุต:
['Hello everyone.',
'Welcome to GeeksforGeeks.',
'You are studying NLP article']
ที่มา: https://www.geeksforgeeks.org/nlp-how-tokenizing-text-sentence-words-works/