2013-04-16 9 views
7

Ich versuche, den ganzen Satz, der ein bestimmtes Wort enthält, aus einem Text zu extrahieren.Python-Extrakt-Satz mit Wort

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

aber es wird mich zurückschicken:

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

statt:

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

Jede Hilfe bitte?

Antwort

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

Sie können str.split verwenden,

>>> 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."] 
7
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"] 

Aber beachten Sie, dass @ jamylak der split -basierte Lösung ist schneller:

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 

Die Geschwindigkeitsdifferenz kleiner, aber immer noch signifikant, für größere Zeichenketten:

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 
+0

+1 nette Antwort! Wenn Sie ein 'txt = txt * 10000' machen, dann wäre'% timeit' das Ergebnis klarer – Kent

+0

Danke Kent. Ich habe einen '% Zeit'-Benchmark für größere Saiten hinzugefügt. – unutbu

16

Keine Notwendigkeit für regex:

>>> 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."] 
+0

Danke jamylak – user2187202

+0

@ user2187202 Sie können meine Antwort akzeptieren, wenn Sie wollen oder die Regex-Lösung akzeptieren, wenn das tatsächlich das war, was Sie brauchten, da Sie es als Regex-Frage markiert haben, ich bin mir nicht sicher, ob das wichtig war oder nicht – jamylak

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

Diese Linie ein wenig seltsam ist; Warum verketten Sie so viele getrennte Strings? Du könntest einfach r '.. + apple. +.'

Wie auch immer, das Problem mit Ihrem regulären Ausdruck ist seine Greedy-Ness. Standardmäßig wird x+ so oft wie möglich mit x übereinstimmen. So wird Ihre .+ so viele Zeichen (alle Zeichen) wie möglich übereinstimmen; einschließlich Punkte und apple s.

Was Sie stattdessen verwenden möchten, ist ein nicht gieriger Ausdruck; Sie können dies normalerweise tun, indem Sie am Ende eine ? hinzufügen: .+?.

Dies wird Ihnen das folgende Ergebnis erhalten zu lassen:

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

Wie Sie Sie nicht mehr sowohl die Apfel-Sätze erhalten sehen, aber immer noch die Me too.. Das liegt daran, dass Sie immer noch die . nach der apple übereinstimmen, was es unmöglich macht, auch den folgenden Satz nicht zu erfassen.

Ein Arbeits regulärer Ausdruck wäre dies: r'\.[^.]*?apple[^.]*?\.'

Hier können Sie sehen nicht auf jedes Zeichen, sondern nur jene Zeichen, die selbst keine Punkte. Wir erlauben auch keine Übereinstimmung mit irgendwelchen Zeichen (denn nach dem apple im ersten Satz gibt es keine nicht-Punkt-Zeichen). dass die Expression unter Verwendung ergibt dies:

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

Offensichtlich in Frage die Probe extract sentence containing substring ist statt
extract sentence containing word.So lösen Sie das extract sentence containing word Problem durch Python ist wie folgt:

Ein Wort kann am Anfang | Ende des Satzes sein. Nicht beschränkt auf das Beispiel in der Frage, würde ich eine allgemeine Funktion ein Wort in einem Satz des Suchens:

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

beschränkt sich auf das Beispiel in der Frage, können wir lösen wie:

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)] 

Der entsprechende Ausgang ist:

['I like to eat apple']