2015-12-06 18 views
7

Vorrei filtrare un elenco di stringhe in python usando regex. Nel seguente caso, mantenendo solo i file con estensione ".npy".stringhe di filtro per regex in un elenco

Il codice che non funziona:

import re 

files = [ '/a/b/c/la_seg_x005_y003.png', 
      '/a/b/c/la_seg_x005_y003.npy', 
      '/a/b/c/la_seg_x004_y003.png', 
      '/a/b/c/la_seg_x004_y003.npy', 
      '/a/b/c/la_seg_x003_y003.png', 
      '/a/b/c/la_seg_x003_y003.npy', ] 

regex = re.compile(r'_x\d+_y\d+\.npy') 

selected_files = filter(regex.match, files) 
print(selected_files) 

La stessa espressione regolare funziona per me in Ruby:

selected = files.select { |f| f =~ /_x\d+_y\d+\.npy/ } 

Cosa c'è di sbagliato con il codice Python?

+1

Si wa n per filtrare gli elementi in 'file' con l'estensione' .npy'? –

risposta

14
selected_files = filter(regex.match, files) 

re.match('regex') è uguale a re.search('^regex') o text.startswith('regex') ma la versione regex. Controlla solo se la stringa inizia con regex.

Quindi, utilizzare re.search() invece:

import re 

files = [ '/a/b/c/la_seg_x005_y003.png', 
      '/a/b/c/la_seg_x005_y003.npy', 
      '/a/b/c/la_seg_x004_y003.png', 
      '/a/b/c/la_seg_x004_y003.npy', 
      '/a/b/c/la_seg_x003_y003.png', 
      '/a/b/c/la_seg_x003_y003.npy', ] 

regex = re.compile(r'_x\d+_y\d+\.npy') 

selected_files = filter(regex.search, files) 
print(selected_files) 

uscita:

['/a/b/c/la_seg_x005_y003.npy', 
'/a/b/c/la_seg_x004_y003.npy', 
'/a/b/c/la_seg_x003_y003.npy'] 

E se si desidera solo per ottenere tutti i file .npy, basta usare str.endswith():

files = [ '/a/b/c/la_seg_x005_y003.png', 
      '/a/b/c/la_seg_x005_y003.npy', 
      '/a/b/c/la_seg_x004_y003.png', 
      '/a/b/c/la_seg_x004_y003.npy', 
      '/a/b/c/la_seg_x003_y003.png', 
      '/a/b/c/la_seg_x003_y003.npy', ] 


selected_files = filter(lambda x: x.endswith('.npy'), files) 

print(selected_files) 
+0

Mi chiedevo perché 'filter()' accetta il metodo 're.search()', poiché quest'ultimo restituisce un'istanza di 'MatchObject' e non un booleano. È spiegato [qui] (http://www.diveintopython.net/functional_programming/filtering_lists.html) in 16.8.3: Il 'search()' -method restituisce un oggetto MatchObject se l'elemento corrisponde e 'filter()' interpreta quello come vero. Altrimenti 'search()' restituisce None, che viene interpretato come False. – user3469861

3

Basta usare search - poiché la corrispondenza inizia a corrispondere dall'inizio alla fine (cioè all'intero) di stringhe e corrispondenze di ricerca in qualsiasi punto della stringa.

import re 

files = [ '/a/b/c/la_seg_x005_y003.png', 
      '/a/b/c/la_seg_x005_y003.npy', 
      '/a/b/c/la_seg_x004_y003.png', 
      '/a/b/c/la_seg_x004_y003.npy', 
      '/a/b/c/la_seg_x003_y003.png', 
      '/a/b/c/la_seg_x003_y003.npy', ] 

regex = re.compile(r'_x\d+_y\d+\.npy') 

selected_files = filter(regex.search, files) 
print(selected_files) 

output-

['/a/b/c/la_seg_x005_y003.npy', '/a/b/c/la_seg_x004_y003.npy', '/a/b/c/la_seg_x003_y003.npy'] 
1

Se match, il modello deve coprire l'intero di ingresso . O si estende espressione regolare:

regex = re.compile(r'.*_x\d+_y\d+\.npy') 

che corrisponderebbe:

['/a/b/c/la_seg_x005_y003.npy', 
'/a/b/c/la_seg_x004_y003.npy', 
'/a/b/c/la_seg_x003_y003.npy'] 

Oppure utilizzare re.search, che

scansioni tramite stringa di ricerca per la prima posizione in cui l'espressione regolare modello produce una partita [...]

1

re.match() cerca una corrispondenza all'inizio della stringa. È possibile utilizzare re.search() invece.

Problemi correlati