2013-04-16 9 views
7

Sto cercando di estrarre tutta la frase contenente una parola specifica da un testo.Frase di estratto di pitone contenente la parola

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

ma mi sta tornando:

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

invece di:

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

Qualsiasi aiuto per favore?

risposta

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

È possibile utilizzare 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."] 
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"] 

Ma si noti che @ di jamylak split soluzione basata su è più veloce:

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 

La differenza di velocità è minore, ma comunque significativa, per i più grandi stringhe:

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 bella risposta! se fai un 'txt = txt * 10000' quindi'% timeit' il risultato sarebbe più chiaro – Kent

+0

Grazie Kent. Ho aggiunto un benchmark '% timeit' per stringhe più grandi. – unutbu

16

Non c'è bisogno di espressioni regolari:

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

Grazie jamylak – user2187202

+0

@ user2187202 Puoi accettare la mia risposta se vuoi o accetta la soluzione regex se in realtà era quello che ti serviva da quando lo hai taggato come una domanda regex, non sono sicuro che fosse essenziale o no – jamylak

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

Questa linea è un po 'strano; perché concatenare così tante stringhe separate? Potresti semplicemente usare r '.. + apple. +.'.

In ogni caso, il problema con la tua espressione regolare è la sua avidità. Per impostazione predefinita, x+ corrisponderà a x tutte le volte che è possibile. Quindi il tuo .+ corrisponderà al maggior numero possibile di caratteri (qualsiasi caratteri); compresi i punti e apple s.

Quello che si desidera utilizzare è un'espressione non-golosa; in genere è possibile farlo aggiungendo un ? alla fine: .+?.

Questo vi farà ottenere il seguente risultato:

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

Come si può vedere che si ottiene non è più sia l'Apple-frasi, ma ancora il Me too.. Questo perché si abbina ancora allo . dopo lo apple, rendendo impossibile non acquisire anche la seguente frase.

Un lavoro espressione regolare sarebbe questo: r'\.[^.]*?apple[^.]*?\.'

Qui non si guarda in qualsiasi personaggi, ma solo i caratteri che non sono essi stessi puntini. Permettiamo anche di non abbinare nessun carattere (perché dopo lo apple nella prima frase non ci sono caratteri senza punti). Utilizzando tale espressione si traduce in questo:

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

Ovviamente, il campione in questione è extract sentence containing substring anziché
extract sentence containing word.Come risolvere il problema extract sentence containing word tramite python è il seguente:

Una parola può essere all'inizio | medio | fine della frase. Non si limita a l'esempio nella questione, vorrei fornire una funzione generale di cercare una parola in una frase:

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

limitata all'esempio in questione, possiamo risolvere come:

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

L'uscita corrispondente è:

['I like to eat apple']