Извлечь предложение Python, содержащее слово

Я пытаюсь извлечь из текста все предложения, содержащие указанное слово.

txt="I like to eat apple. Me too. Let's go buy some apples."
txt = "." + txt
re.findall(r"\."+".+"+"apple"+".+"+"\.", txt)

но он возвращает меня:

[".I like to eat apple. Me too. Let's go buy some apples."]

вместо :

[".I like to eat apple., "Let's go buy some apples."]

Любая помощь, пожалуйста?


person user2187202    schedule 16.04.2013    source источник


Ответы (6)


Нет необходимости в регулярном выражении:

>>> txt = "I like to eat apple. Me too. Let's go buy some apples."
>>> [sentence + '.' for sentence in txt.split('.') if 'apple' in sentence]
['I like to eat apple.', " Let's go buy some apples."]
person jamylak    schedule 16.04.2013
comment
@user2187202 user2187202 Вы можете принять мой ответ, если хотите, или принять решение с регулярным выражением, если это действительно то, что вам нужно, поскольку вы пометили его как вопрос с регулярным выражением, хотя я не уверен, было ли это важно или нет. - person jamylak; 16.04.2013

In [7]: import re

In [8]: txt=".I like to eat apple. Me too. Let's go buy some apples."

In [9]: re.findall(r'([^.]*apple[^.]*)', txt)
Out[9]: ['I like to eat apple', " Let's go buy some apples"]

Но обратите внимание, что решение @jamylak на основе split работает быстрее:

In [10]: %timeit re.findall(r'([^.]*apple[^.]*)', txt)
1000000 loops, best of 3: 1.96 us per loop

In [11]: %timeit [s+ '.' for s in txt.split('.') if 'apple' in s]
1000000 loops, best of 3: 819 ns per loop

Разница в скорости меньше, но все же значительна для больших строк:

In [24]: txt = txt*10000

In [25]: %timeit re.findall(r'([^.]*apple[^.]*)', txt)
100 loops, best of 3: 8.49 ms per loop

In [26]: %timeit [s+'.' for s in txt.split('.') if 'apple' in s]
100 loops, best of 3: 6.35 ms per loop
person unutbu    schedule 16.04.2013
comment
+1 хороший ответ! если вы сделаете txt=txt*10000, то %timeit результат будет более четким - person Kent; 16.04.2013
comment
Спасибо, Кент. Я добавил тест %timeit для больших строк. - person unutbu; 16.04.2013

Вы можете использовать str.split,

>>> txt="I like to eat apple. Me too. Let's go buy some apples."
>>> txt.split('. ')
['I like to eat apple', 'Me too', "Let's go buy some apples."]

>>> [ t for t in txt.split('. ') if 'apple' in t]
['I like to eat apple', "Let's go buy some apples."]
person Adem Öztaş    schedule 16.04.2013

r"\."+".+"+"apple"+".+"+"\."

Эта линия немного странная; зачем объединять столько отдельных строк? Вы можете просто использовать r'..+apple.+.'.

В любом случае, проблема с вашим регулярным выражением заключается в его жадности. По умолчанию x+ будет соответствовать x так часто, как это возможно. Таким образом, ваш .+ будет соответствовать как можно большему количеству символов (любых символов); включая точки и apples.

Вместо этого вы хотите использовать нежадное выражение; обычно это можно сделать, добавив ? в конце: .+?.

В результате вы получите следующий результат:

['.I like to eat apple. Me too.']

Как видите, вы больше не получаете оба предложения с яблоками, но по-прежнему получаете Me too.. Это потому, что вы все еще соответствуете . после apple, что делает невозможным не захватить и следующее предложение.

Рабочее регулярное выражение будет таким: r'\.[^.]*?apple[^.]*?\.'

Здесь вы не смотрите на какие-либо символы, а только на те символы, которые сами по себе не являются точками. Мы также разрешаем вообще не совпадать ни с какими символами (поскольку после apple в первом предложении нет символов, отличных от точки). Использование этого выражения приводит к следующему:

['.I like to eat apple.', ". Let's go buy some apples."]
person poke    schedule 16.04.2013

Очевидно, что речь идет об образце extract sentence containing substring, а не
extract sentence containing word. Как решить проблему extract sentence containing word через python, выглядит следующим образом:

Слово может стоять в начале|середине|конце предложения. Не ограничиваясь примером в вопросе, я бы предоставил общую функцию поиска слова в предложении:

def searchWordinSentence(word,sentence):
    pattern = re.compile(' '+word+' |^'+word+' | '+word+' $')
    if re.search(pattern,sentence):
        return True

ограниченный примером в вопросе, мы можем решить, как:

txt="I like to eat apple. Me too. Let's go buy some apples."
word = "apple"
print [ t for t in txt.split('. ') if searchWordofSentence(word,t)]

Соответствующий вывод:

['I like to eat apple']
person YJ. Yang    schedule 13.12.2017

person    schedule
comment
как я могу получить только apple, добавив границы: [ 'Я люблю есть яблоко.'] - person Hari; 26.10.2018