我试图使用python中的正则表达式从段落中提取一个句子。
通常,我测试的代码正确地提取了句子,但是在下面的段落中,句子没有被正确地提取。
该段:
“但在疟疾感染和脓毒症的情况下,整个身体的树突状细胞都集中在提醒免疫系统,这阻止了他们发现和应对任何新的感染。一种新型疫苗?
守则:
def splitParagraphIntoSentences(paragraph):
import re
sentenceEnders = re.compile('[.!?][\s]{1,2}(?=[A-Z])')
sentenceList = sentenceEnders.split(paragraph)
return sentenceList
if __name__ == '__main__':
f = open("bs.txt", 'r')
text = f.read()
mylist = []
sentences = splitParagraphIntoSentences(text)
for s in sentences:
mylist.append(s.strip())
for i in mylist:
print i当用上面的段落进行测试时,它给出的输出与输入段落完全一样,但是输出应该如下所示-
但是在疟疾感染和脓毒症的情况下,整个身体的树突状细胞都集中在提醒免疫系统,这阻止了他们对任何新的感染进行检测和反应。
一种新型疫苗
正则表达式有什么问题吗?
发布于 2011-12-11 16:39:07
作为一个例子,你贴出的这个段落的第一句包含在双引号"中,结尾引号紧跟在句号“感染”之后。
您的regexp [.!?]\s{1,2}正在寻找一个句点,一个或两个空格作为句子结束符,所以它不会捕获它。
它可以通过允许可选的收尾引号来适应这种情况:
sentenceEnders = re.compile(r'''[.!?]['"]?\s{1,2}(?=[A-Z])''')但是,使用上面的regexp,您将从句子中删除末尾引号。保留它要稍微复杂一些,并且可以通过一个回顾性断言来完成:
sentenceEnders = re.compile(r'''(?<=[.!?]['"\s])\s*(?=[A-Z])''')但是,请注意,在许多情况下,基于regexp的拆分器失败,例如:
。
发布于 2011-12-11 19:21:44
里卡多·穆里的回答是正确的,但我想我会在这个问题上讲得更清楚一些。
对于PHP有一个类似的问题:php sentence boundaries detection。我对这个问题的回答包括处理“先生”、“夫人”等例外情况。还有“小”。我已经对这个正则表达式进行了调整,使其能够与Python一起工作(这对lookbehinds设置了更多的限制)。下面是一个经过修改和测试的脚本版本,它使用这个新的regex:
def splitParagraphIntoSentences(paragraph):
import re
sentenceEnders = re.compile(r"""
# Split sentences on whitespace between them.
(?: # Group for two positive lookbehinds.
(?<=[.!?]) # Either an end of sentence punct,
| (?<=[.!?]['"]) # or end of sentence punct and quote.
) # End group of two positive lookbehinds.
(?<! Mr\. ) # Don't end sentence on "Mr."
(?<! Mrs\. ) # Don't end sentence on "Mrs."
(?<! Jr\. ) # Don't end sentence on "Jr."
(?<! Dr\. ) # Don't end sentence on "Dr."
(?<! Prof\. ) # Don't end sentence on "Prof."
(?<! Sr\. ) # Don't end sentence on "Sr."
\s+ # Split on whitespace between sentences.
""",
re.IGNORECASE | re.VERBOSE)
sentenceList = sentenceEnders.split(paragraph)
return sentenceList
if __name__ == '__main__':
f = open("bs.txt", 'r')
text = f.read()
mylist = []
sentences = splitParagraphIntoSentences(text)
for s in sentences:
mylist.append(s.strip())
for i in mylist:
print i您可以看到它如何处理特殊情况,并且很容易根据需要添加或删除它们。它正确地分析了你的示例段落。它还正确地分析了以下测试段落(其中包括更多的特殊情况):
这是第一句。第二句!第三句?第四句。第五句!第六句?句子“七”第八句!琼斯博士说:“史密斯太太,你有一个可爱的女儿!”
但请注意,还有其他例外可能失败,Riccardo已经正确地指出。
发布于 2011-12-11 16:37:39
是的,出了点问题。你只考虑分隔符后面有一两个空格,然后是大写字母,那么“新型疫苗”的结尾是什么?例如,句子不会匹配。
我对空格也不会有太大的限制,除非它是一种意图(案文可能没有很好的格式),因为。“你好,幸运儿!你今天好吗?”不会分裂的。
我也不明白你的例子,为什么只有第一句是附在“?
总之:
>>> Text="""But in the case of malaria infections, dendritic cells and stuff.
A new type of vaccine? My uncle!
"""
>>> Sentences = re.split('[?!.][\s]*',Text)
>>> Sentences
['But in the case of malaria infections, dendritic cells and stuff',
'A new type of vaccine',
'My uncle',
'']您还可以过滤空句子:
>>> NonemptyS = [ s for s in Senteces if s ]https://stackoverflow.com/questions/8465335
复制相似问题