2010-10-11 4 views
0

Какое правильное выражение regex использует re.search(), чтобы найти и вернуть расширение файла в строке.python regex question

Такие, как: (.+).(avi|rar|zip|txt)

Мне нужно найти строку и, если она содержит любой из этих AVI, RAR и т.д.) возвращать только это расширение.

Спасибо!

EDIT: следует добавить, что является должно быть чувствительно к регистру

+0

Вы действительно хотите найти строку для первого появления чего-то вроде '.avi' или вы хотите, чтобы проверить, что строка заканчивается с этим? Другой вопрос, это строковый общий текст: «Фред прислал мне фью.rar today "или он должен содержать имя файла или путь, расширение которого вы хотите извлечь? –

ответ

1

Короткий интерактивный пробег:

>>> import re 
>>> pat="(.+)\.(avi|rar|zip|txt)" 
>>> re.search(pat, "abcdefg.zip", re.IGNORECASE).groups() 
('abcdefg', 'zip') 
>>> re.search(pat, "abcdefg.ZIP", re.IGNORECASE).groups() 
('abcdefg', 'ZIP') 
>>> 
+0

В данном конкретном случае это не проблема, но для регулярных выражений рекомендуется использовать строки, чтобы избежать двойного экранирования. используйте 'r" (. +) \. (avi | rar | zip | txt) "' – SingleNegationElimination

6

Понадобится:

(.)\.(avi|rar|zip|txt)$ 

Обратите внимание на обратную косую черту, чтобы избежать точки. Это заставит его искать буквальную точку, а не любой символ.

Чтобы сделать регистр нечувствительным к регистру, используйте флаг RE.I в своем вызове search.

re.search(r'(.)\.(avi|rar|zip|txt)$', string, re.I) 
+2

Итак, есть ли флаг, который делает интерпретатор Python нечувствительным к регистру? В противном случае нам нужно« импортировать re как RE », чтобы иметь возможность найти «RE.I' ... –

+1

Вы можете сделать его более смутно более эффективным и менее смутно точнее, что его ищут, изменив его на'. \. (avi | rar | zip | txt) $ ': это обеспечит что перед точкой есть какой-то символ, и что расширение файла находится в конце строки. Таким образом, вы получите первое совпадение, являющееся расширением, а не вторым, и вы не получите соответствия, которое вам не нужно. – intuited

+0

@Nick T: флаг re.I предназначен только для модуля регулярных выражений. Я не знаю, как сделать остальную часть python без учета регистра. – JoshD

0

Так как я думаю, что регулярное выражение зла ...

def return_extension(filename): 
    '''(This functions assumes that filenames such as `.foo` have extension 
    `foo`.) 
    ''' 
    tokens = filename.split('.') 

    return '' if len(tokens) == 1 else tokens[-1] 

... Я защищаю просто разбор файла.

+0

Переосмыслить колесо, но не изобретать осей еще более злобно. –

0

Если вы знаете, что расширение находится в самом конце строки, это должно хорошо работать:

.\.(avi|rar|zip|txt)$ 
  • Первый бит гарантирует, что есть какой-то символ перед точкой.

  • $ указывает, что расширение файла находится в конце строки, то есть $ означает «строка заканчивается здесь». Для подробностей об этом, в том числе о некоторых случаях с новыми символами, о которых вы должны знать, см. Обсуждение комментариев для JoshD's answer, а также запись для $ в docs.

Итак единственная запись в match.groups() кортежа, т.е. match.groups()[0], будет само по себе расширение.

+0

@intuited: -1. s/некоторые кромки/FAIL/ –

+0

@ Джон Маккин: Дерьмо, правда? Я не могу думать ни о чем. Какой пример? – intuited

+0

@intuited: "" "Обоснование blah \ Z в не-многострочном режиме по умолчанию заключается в том, что re.match (" blah $ "," blah \ n ") не вернет None" "" –

8

стандартная библиотека лучше;)

>>> os.path.splitext('hello.py') 
('hello', '.py') 
+0

+1 это правильный инструмент для работы! – katrielalex