2015-12-06 15 views
7

Ich möchte eine Liste von Zeichenfolgen in Python mit Regex filtern. Im folgenden Fall behalten Sie nur die Dateien mit der Erweiterung ".npy".Filter Strings von Regex in einer Liste

Der Code, der nicht funktioniert:

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) 

Das gleiche Regex funktioniert für mich in Ruby:

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

Was ist los mit dem Python-Code?

+1

Sie wa n um die Elemente in 'Dateien' mit der Erweiterung' .npy' zu filtern? –

Antwort

14
selected_files = filter(regex.match, files) 

re.match('regex') gleich re.search('^regex') oder text.startswith('regex') aber regex Version. Es wird nur überprüft, ob die Zeichenfolge mit der Regex beginnt.

So verwenden re.search() statt:

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) 

Ausgang:

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

Und wenn man nur alle die .npy Dateien erhalten möchten, verwenden Sie einfach 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

Ich fragte mich, warum 'filter()' die 're.search()' -Methode akzeptiert, da letztere eine Instanz von 'MatchObject' zurückgibt und keine boolesche. Es wird [hier] (http://www.diveintopython.net/functional_programming/filtering_lists.html) in 16.8.3 erklärt: Die 'search()' -Methode gibt ein MatchObject zurück, wenn das Item übereinstimmt und 'filter()' interpretiert das als Wahr. Andernfalls gibt 'search()' 'None zurück, was als False interpretiert wird. – user3469861

3

Verwenden Sie einfach search - da Übereinstimmung beginnt, vom Anfang bis zum Ende (d. H. Ganz) von String- und Suchtreffern an einer beliebigen Stelle in der Zeichenfolge zu entsprechen.

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

Wenn Sie match, das Muster der gesamte Eingabe abdecken muss. Entweder erweitern Sie regulären Ausdruck:

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

Oder re.search, die für die ersten Stelle wo der reguläre Ausdruck

Scans durch Saiten verwenden:

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

Welche würde passen Muster erzeugt eine Übereinstimmung [...]

1

re.match() sucht nach einer Übereinstimmung am Anfang der Zeichenfolge. Sie können stattdessen re.search() verwenden.

Verwandte Themen