Я пытаюсь написать регулярное выражение, которое преобразует полное имя файла пути в короткое имя файла для заданного типа файла, за вычетом расширения файла.
Например, я пытаюсь получить только имя файла .bar из строки, используя
re.search('/(.*?)\.bar$', '/def_params/param_1M56/param/foo.bar')
Согласно Python re docs, *?
- это нелогичная версия *
, поэтому я ожидал получить
'foo'
возвращен для match.group(1)
, но вместо этого я получил
'def_params/param_1M56/param/foo'
Что мне здесь не хватает о жадности?
То, что вам не хватает, связано не столько с жадностью, сколько с механизмами регулярных выражений: они работают слева направо, поэтому /
соответствует как можно раньше, а .*?
затем вынуждается работать оттуда, В этом случае лучшее регулярное выражение вовсе не связано с жадностью (вам нужно вернуться к работе, но это может занять очень много времени, если есть много косых черт), но более явный шаблон:
'/([^/]*)\.bar$'
Я бы предложил изменить ваше регулярное выражение, чтобы оно не зависело от жадности.
Вы хотите только имя файла перед расширением .bar
и все после окончательного /
. Это должно сделать:
re.search(`/[^/]*\.bar$`, '/def_params/param_1M56/param/foo.bar')
Что это значит, он соответствует /
, а затем не более или более символов (насколько это возможно) не /
, а затем .bar
.
.
в вашем регулярном выражении совпадает с чем угодно, вместо .
файла расширения. Убедитесь, что вы избегаете .
с \.
Мне нравится regex, но здесь нет необходимости.
path = '/def_params/param_1M56/param/foo.bar'
print path.rsplit('/',1)[1].rsplit('.')[0]
path = '/def_params/param_1M56/param/fululu'
print path.rsplit('/',1)[1].rsplit('.')[0]
path = '/def_params/param_1M56/param/one.before.two.dat'
print path.rsplit('/',1)[1].rsplit('.',1)[0]
результат
foo
fululu
one.before.two
path.split('/')[-1].split('.')[0]
Другие люди ответили на вопрос о регулярном выражении, но в этом случае более эффективный способ, чем регулярное выражение:
file_name = path[path.rindex('/')+1 : path.rindex('.')]
Регулярные выражения начинаются справа. Поместите a * в начале и он должен работать.
Я не претендую на то, чтобы хорошо понять неживые операторы, но решением этой конкретной проблемы было бы использовать ([^/] *?)
попробуйте этот вариант для размера:
match = re.search('. */(. *?). bar $', '/def_params/param_1M56/param/foo.bar')
'.*/
, Я не думаю, что вам действительно нужно .*?
, .*
тоже будет работать :) Не могли бы вы отредактировать свой вопрос, чтобы я снова мог вас проголосовать?