2016-02-23 4 views
1

У меня есть список files строк в следующем формате:Extract ИНТ между двумя строками в Python

files = ['/misc/lmbraid17/bensch/u-net-3d/2dcellnet/2dcellnet_v6w4l1/2dcellnet_v6w4l1_snapshot_iter_418000.caffemodel.h5', 
'/misc/lmbraid17/bensch/u-net-3d/2dcellnet/2dcellnet_v6w4l1/2dcellnet_v6w4l1_snapshot_iter_502000.caffemodel.h5', ...] 

Я хочу, чтобы извлечь int между iter_ и .caffemodel и возвращает список тех Интс.

После некоторых исследований я придумал это решение, которое делает трюк, но мне было интересно, есть ли более элегантный/pythonic способ сделать это, возможно, используя понимание списка?

li = [] 
for f in files: 
    tmp = re.search('iter_[\d]+.caffemodel', f).group() 
    li.append(int(re.search(r'\d+', tmp).group())) 
+1

Вы должны использовать группу захвата. 'r'iter _ (\ d +) \. caffemodel'', а затем получить доступ к значению через' .группу (1) '. –

ответ

3

Просто добавить еще одно возможное решение: объединить имена файлов в одну большую строку (выглядит как все конец с h5, так что нет никакой опасности создания нежелательные матчи) и использовать re.findall на том, что:

import re 
li = [int(d) for d in re.findall(r'iter_(\d+)\.caffemodel', ''.join(files))] 
+0

Мне нравится ваше решение ... Это очень читаемо (лучше, чем я придумал;)) – Dominic

2

Используйте только:

li = [] 
for f in files: 
    tmp = int(re.search('iter_(\d+)\.caffemodel', f).group(1)) 
    li.append(tmp) 

Если положить выражение в скобках, что создает еще одну группу соответствующих выражений.

+1

Зачем использовать ленивый квантификатор? Здесь избыточно. Используйте жадную версию, она более эффективна. И избегайте точки. И используйте строковый литерал, когда вы объявляете регулярное выражение (просто лучшая практика). –

+0

Все это правда. – martin

+0

Ницца! Я сам смог генерировать понимание: 'li = [int (re.search ('iter _ (\ d +) \. Caffemodel', f) .group (1)) для f в файлах]' - я не знал о операция '()'. Спасибо :) – Dominic

1

решение с пониманием списка, как вы хотели:

import re 

re_model_id = re.compile(r'iter_(?P<model_id>\d+).caffemodel') 
li = [int(re_model_id.search(f).group('model_id')) for f in files] 
1

Без регулярных выражений:

files = [ 
    '/misc/lmbraid17/bensch/u-net-3d/2dcellnet/2dcellnet_v6w4l1/2dcellnet_v6w4l1_snapshot_iter_418000.caffemodel.h5', 
    '/misc/lmbraid17/bensch/u-net-3d/2dcellnet/2dcellnet_v6w4l1/2dcellnet_v6w4l1_snapshot_iter_502000.caffemodel.h5'] 

print([f.rsplit("_", 1)[1].split(".", 1)[0] for f in files]) 
['418000', '502000'] 

Или, если вы хотите быть более конкретным:

print([f.rsplit("iter_", 1)[1].split(".caffemodel", 1)[0] for f in files]) 

Но ваш шаблон кажется повторить, так что первое решение будет вполне достаточно.

Вы также можете нарезать с помощью находку и RFIND:

print([f[f.find("iter_")+5: f.rfind("caffe")-1] for f in files]) 
['418000', '502000']