2015-12-06 12 views
7

Chciałbym filtrować listę ciągów w Pythona za pomocą regex. W następującym przypadku przechowuj tylko pliki z rozszerzeniem ".npy".ciągi filtrów według regex na liście

Kod, który nie działa:

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) 

To samo wyrażenie regularne działa na mnie w Ruby:

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

Co jest nie tak z kodem Pythona?

+1

You wa n do filtrowania elementów w 'plikach' z rozszerzeniem' .npy'? –

Odpowiedz

14
selected_files = filter(regex.match, files) 

re.match('regex') jest równa re.search('^regex') lub text.startswith('regex') ale wersji regex. Sprawdza tylko, czy ciąg rozpoczyna się od regex.

więc używać re.search() zamiast:

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) 

wyjściowa:

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

A jeśli po prostu chcesz uzyskać wszystkie .npy plików, wystarczy użyć 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

Zastanawiam się, dlaczego 'filter()' akceptuje 're.search()' -metod, ponieważ ten drugi zwraca instancję 'MatchObject', a nie boolean. Wyjaśniono [tutaj] (http://www.diveintopython.net/functional_programming/filtering_lists.html) w 16.8.3: Metoda 'search()' zwraca obiekt MatchObject, jeśli element pasuje i interpretuje 'filter()' to prawda. W przeciwnym razie 'search()' zwraca None, co jest interpretowane jako False. – user3469861

3

Po prostu użyj search - od dopasowania zaczyna się od początku do końca (tj. Całego) ciągu znaków i dopasowań wyszukiwania w dowolnym miejscu ciągu.

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

Jeśli match, wzór musi obejmować całą wejście . Albo przedłużyć Ci wyrażenia regularnego:

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

Które pasuje:

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

Albo użyć re.search, co

skanów poprzez ciąg szukasz pierwszym miejscu gdzie wyrażenie regularne wzór tworzy dopasowanie [...]

1

szuka dopasowania na początku łańcucha. Zamiast tego możesz użyć re.search().

Powiązane problemy