我需要从文本中获取前N个句子,其中句子的最后一个字符可以是句号,冒号或分号。例如,给出这个文本:
Lorem ipsum, dolor sit amet. consectetur adipisicing elit; sed do eiusmod tempor.
incididunt ut labore: et dolore magna aliqua. Ut enim ad. minim veniam.
前4个句子是,
Lorem ipsum, dolor sit amet. consectetur adipisicing elit; sed do eiusmod tempor.
incididunt ut labore:
目前,我的代码使用.
,:
和;
作为分隔符来拆分字符串,然后加入结果。
import re
sentences = re.split('\. |: |;', text)
summary = ' '.join(sentences[:4])
但它会从结果中删除分隔符。我对正则表达式或基本字符串操作持开放态度。
答案 0 :(得分:4)
>>> import re
>>> text = "Lorem ipsum, dolor sit amet. consectetur adipisicing elit; sed do eiusmod tempor. incididunt ut labore: et dolore magna aliqua. Ut enim ad. minim veniam."
>>> ' '.join(re.split(r'(?<=[.:;])\s', text)[:4])
'Lorem ipsum, dolor sit amet. consectetur adipisicing elit; sed do eiusmod tempor. incididunt ut labore:'
这样的效果会更高效,可以通过格式化4
:
>>> re.match(r'(?:[^.:;]+[.:;]){4}', text).group()
'Lorem ipsum, dolor sit amet. consectetur adipisicing elit; sed do eiusmod tempor. incididunt ut labore:'
答案 1 :(得分:3)
所以,我知道这个问题是关于使用正则表达式来查找句子,但是,出于同样的原因,正则表达式不是解析html的正确选择(不同类别的语法),正则表达式是一个更糟糕的选择。涉及自然语言。
如果您的目标是实际描述句子,则必须寻找其他工具。我个人会推荐nltk提供的Punkt句子标记器。下面是一个示例,说明为什么这是一个比正则表达式更好的选择。
Punkt knows that the periods in Mr. Smith and Johann S. Bach do not mark
sentence boundaries. And sometimes sentences can start with non-capitalized
words. i is a good variable name.
答案 2 :(得分:1)
可以将re.finditer
与itertools.islice
结合使用,并进行字符串切片(以避免加入并保留分隔符):
import re
from itertools import islice
delims = re.finditer('[.:;]', s)
try:
print s[:next(islice(delims, 3, None)).end()]
except StopIteration:
print s # whole string instead maybe as there's not enough delimiters
答案 3 :(得分:0)
import re
sentenceEnd = re.compile('[.!?][\s]{1,2}(?=[A-Z])')
sentenceLists = sentenceEnd.split(text, re.UNICODE)
可以使用上面的方法,它会做的是寻找一段时间,并确保之后的下一个字符是一个大写字母,并且在句点和下一个字母之间有一个空格,这将需要护理AM等病例。文本基本上是原始文本的位置,并确保它是单一的。