2014-01-29 6 views
2

Я экспериментирую с примитивными регулярными выражениями, чтобы помочь мне найти и загрузить файлы. Соответственно, мне было интересно, почему следующий код не работает? Я понимаю, что re.findall создает объект, и я бы представил это, где я сбился с пути. Спасибо, как всегда.Основы регулярных выражений python

server_list1=('part002.csv.gz' , '2014-01-28', 'part001.csv.gz', '2014-01-28', 'part002.csv.gz', '2014-01-25') 

x=[] 

for item in server_list1: 

    if re.findall(r'gz', item) == 1 : 

     x.append(item) 
+0

findall возвращает список строк соответствия. Обратитесь к документации. – krait

ответ

3

Попробуйте уронить == 1, как это:

for item in server_list1: 
    if re.findall(r'gz', item) : 
     x.append(item) 

# x => ['part002.csv.gz', 'part001.csv.gz', 'part002.csv.gz'] 

На стороне записки, регулярное выражение будет соответствовать gzгде-нибудь во входной строке. Чтобы убедиться, что строка заканчивается gz, используйте концевой якорь ($), как в gz$, или \.gz$, если вы хотите, чтобы он заканчивался на .gz.

+0

искреннее спасибо. –

4

Да, re.findall возвращает объект (как и все в Python). Однако этот объект представляет собой список совпадений, который никогда не будет равен целому числу 1.


Поскольку пустые списки вычисляться False в Python, вы можете решить эту проблему, просто напишите:

if re.findall(r'\.gz$', item): 

Ниже демонстрация:

>>> import re 
>>> server_list1=('part002.csv.gz' , '2014-01-28', 'part001.csv.gz', '2014-01-28', 'part002.csv.gz', '2014-01-25') 
>>> x=[] 
>>> for item in server_list1: 
...  if re.findall(r'\.gz$', item): 
...   x.append(item) 
... 
>>> x 
['part002.csv.gz', 'part001.csv.gz', 'part002.csv.gz'] 
>>> 

Кроме того, вы заметите, что Я изменил шаблон Regex на \.gz$ вместо gz. Новый шаблон будет соответствовать .gz в конце строки, а не gz в любом месте строки.


Однако, как @krait упомянуто ниже, вы никогда не должны использовать re.findall, чтобы проверить, если одна строка содержит шаблон. Вместо этого, вы должны использовать re.search:

>>> import re 
>>> server_list1=('part002.csv.gz' , '2014-01-28', 'part001.csv.gz', '2014-01-28', 'part002.csv.gz', '2014-01-25') 
>>> x=[] 
>>> for item in server_list1: 
...  if re.search(r'\.gz$', item): 
...   x.append(item) 
... 
>>> x 
['part002.csv.gz', 'part001.csv.gz', 'part002.csv.gz'] 
>>> 

Или, еще лучше в этом случае, чтобы избавиться от Regex вообще и использовать str.endswith:

>>> server_list1=('part002.csv.gz' , '2014-01-28', 'part001.csv.gz', '2014-01-28', 'part002.csv.gz', '2014-01-25') 
>>> x=[] 
>>> for item in server_list1: 
...  if item.endswith('.gz'): 
...   x.append(item) 
... 
>>> x 
['part002.csv.gz', 'part001.csv.gz', 'part002.csv.gz'] 
>>> 
+0

В этом случае Findall является расточительным, так как он должен построить список строк, которые никогда не используются. – krait

+0

если re.search (r '\. Gz $', item): возвращает true или false в зависимости от того, что там есть? –

+1

@ChaseCB - Фактически, он возвращает ['re.MatchObject'] (http://docs.python.org/2/library/re.html#re.MatchObject), если он находит шаблон или' None', если он не может. Первый будет оценивать значение «True», но последний будет оценивать значение «False» – iCodez

1

Используйте наиболее прагматичный подход к данной проблеме , Это не требует соответствия регулярных выражений.

server_list1 = ('part002.csv.gz' , '2014-01-28', 'part001.csv.gz', '2014-01-28', 'part002.csv.gz', '2014-01-25') 

x = [] 

for item in server_list1: 
    if item.endswith('.gz'): 
     x.append(item) 

Или более кратко:

x = filter((lambda item: item.endswith('.gz')), server_list1) 

Просто с помощью in оператора, или регулярное выражение, как вы определили (в отличие от r'\.gz$') будет неправильно соответствовать figz.png, например.

Также кажется, что вы храните гетерогенные данные в одном кортеже. Во-первых, я бы рекомендовал вам использовать список вместо этого, поскольку это более подходит для обработки переменной количества записей.Во-вторых, сделать ваши данные униформу: используйте список кортежей, как:

[('part002.csv.gz', '2014-01-28'), ('part001.csv.gz', '2014-01-28'), ('part002.csv.gz', '2014-01-25')] 

Таким образом, вы можете быть уверены, что все имена файлов принадлежат сохраняются в первом индексе кортежа, и все даты сохраняются во втором кортеже индекс. С учетом server_list1 указанная выше структура может быть произведена:

data = zip(server_list1[::2], server_list1[1::2]) 
+0

, спасибо .... никогда не видел конца с функцией(). знание - сила. –

Смежные вопросы