Дегридификация регулярного выражения в python - PullRequest
1 голос
/ 21 апреля 2011

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

Например, я пытаюсь получить толькоимя .bar-файла из строки, используя

re.search('/(.*?)\.bar$', '/def_params/param_1M56/param/foo.bar')

В соответствии с документацией Python, *? - это несносная версия *, поэтому я ожидал получить

'foo'

вернулся за match.group(1), но вместо этого я получил

'def_params/param_1M56/param/foo'

Что мне здесь не хватает из-за жадности?

Ответы [ 7 ]

8 голосов
/ 21 апреля 2011

То, что вам не хватает, - это не столько жадность, сколько движки регулярных выражений: они работают слева направо, поэтому / совпадает как можно раньше, а затем .*? заставляет работать , В этом случае, лучшее регулярное выражение вообще не включает в себя жадность (для этого нужно вернуться назад; это будет работать, но может потребоваться очень много времени для запуска, если есть много слэшей), но более явный шаблон:

'/([^/]*)\.bar$'
3 голосов
/ 21 апреля 2011

Я бы предложил изменить ваше регулярное выражение, чтобы оно не зависело от жадности.

Вам нужно только имя файла до расширения .bar и все после финального /. Это должно сделать:

re.search(`/[^/]*\.bar$`, '/def_params/param_1M56/param/foo.bar')

То, что это делает, соответствует /, затем нулю или более (максимально возможному) символов, которые не /, а затем .bar.

0 голосов
/ 21 апреля 2011

Другие люди ответили на вопрос о регулярном выражении, но в этом случае есть более эффективный способ, чем регулярное выражение:

file_name = path[path.rindex('/')+1 : path.rindex('.')]
0 голосов
/ 21 апреля 2011

Мне нравится регулярное выражение, но здесь оно не нужно.

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
0 голосов
/ 21 апреля 2011

примерьте размер:

match = re.search ('. * / (. *?). Bar $', '/def_params/param_1M56/param/foo.bar')

0 голосов
/ 21 апреля 2011

Регулярные выражения начинаются справа. Поставьте. * В начале, и оно должно работать.

0 голосов
/ 21 апреля 2011

Я не претендую на то, что хорошо разбираюсь в не жадных операторах, но решением этой конкретной проблемы будет использование ([^ /] *?)

...