Извлечь имя файла из пути, независимо от того, какой формат os / path

Какую библиотеку Python я могу использовать для извлечения имен файлов из путей, независимо от того, что может быть в операционной системе или в формате пути?

Например, я хотел бы, чтобы все эти пути вернули мне c :

 a/b/c/ a/b/c \a\b\c \a\b\c\ a\b\c a/b/../../a/b/c/ a/b/../../a/b/c 

13 Solutions collect form web for “Извлечь имя файла из пути, независимо от того, какой формат os / path”

Использование os.path.split или os.path.basename как показывают другие, не будет работать во всех случаях: если вы запускаете скрипт в Linux и пытаетесь обработать классический путь в стиле Windows, он не сработает.

Пути Windows могут использовать либо обратную косую черту, либо косую черту в качестве разделителя путей. Поэтому модуль ntpath (который эквивалентен os.path при работе в Windows) будет работать для всех (1) путей на всех платформах.

 import ntpath ntpath.basename("a/b/c") 

Конечно, если файл заканчивается косой чертой, базовое имя будет пустым, поэтому сделайте свою собственную функцию для решения этой проблемы:

 def path_leaf(path): head, tail = ntpath.split(path) return tail or ntpath.basename(head) 

Проверка:

 >>> paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c', ... 'a/b/../../a/b/c/', 'a/b/../../a/b/c'] >>> [path_leaf(path) for path in paths] ['c', 'c', 'c', 'c', 'c', 'c', 'c'] 

(1) Существует одна оговорка: имена файлов Linux могут содержать обратную косую черту . Поэтому в linux r'a/b\c' всегда ссылается на файл b\c в папке a , тогда как в Windows он всегда ссылается на c файл в подпапке b папки. Поэтому, когда в пути используются как прямая, так и обратная косая черта, вам нужно знать связанную платформу, чтобы она могла правильно ее интерпретировать. На практике обычно безопасно предполагать, что это путь к окну, поскольку обратные слэши редко используются в именах файлов Linux, но имейте это в виду, когда вы кодируете, чтобы не создавать случайные дыры в безопасности.

Фактически, есть функция, которая возвращает именно то, что вы хотите

 print os.path.basename(your_path) 

os.path.split – это функция, которую вы ищете

 head, tail = os.path.split("/tmp/d/a.dat") >>> print tail a.dat >>> print head /tmp/d 
 import os head, tail = os.path.split(p) print tail 

Предположим, что p – входная строка, хвост – это то, что вы хотите.

Подробные сведения см. В документах модуля python os.

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

 >>> import os >>> path = 'a/b/c/' >>> path = path.rstrip(os.sep) # strip the slash from the right side >>> os.path.basename(path) 'c' 

Второй уровень:

 >>> os.path.filename(os.path.dirname(path)) 'b' 

update: Я думаю, lazyr предоставил правильный ответ. Мой код не будет работать с оконными путями в Unix-системах и наоборот по сравнению с unix-подобными путями в системе Windows.

 fname = str("C:\Windows\paint.exe").split('\\')[-1:][0] 

это вернет: paint.exe

измените значение sep функции split в отношении вашего пути или ОС.

Это работает для linux и windows, а также со стандартной библиотекой

 paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c', 'a/b/../../a/b/c/', 'a/b/../../a/b/c'] def path_leaf(path): return path.strip('/').strip('\\').split('/')[-1].split('\\')[-1] [path_leaf(path) for path in paths] 

Результаты:

 ['c', 'c', 'c', 'c', 'c', 'c', 'c'] 

Я никогда не видел двойных обратных путей, они существуют? Встроенная функция python module os не подходит для них. Все остальные работают, также предостережение, данное вами с помощью os.path.normpath() :

 paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c', ... 'a/b/../../a/b/c/', 'a/b/../../a/b/c', 'a/./b/c', 'a\b/c'] for path in paths: os.path.basename(os.path.normpath(path)) 

Разделитель Windows может быть в имени файла Unix или в пути Windows. Разделитель Unix может существовать только в пути Unix. Наличие разделителя Unix указывает путь, отличный от Windows.

Следующее разделит разделитель разделителя ОС на отдельный разделитель, затем разделит и вернем самое правое значение. Это уродливое, но простое, основанное на предположении выше. Если предположение неверно, обновите его, и я обновлю этот ответ, чтобы соответствовать более точным условиям.

 a.rstrip("\\\\" if a.count("/") == 0 else '/').split("\\\\" if a.count("/") == 0 else '/')[-1] 

образец кода:

 b = ['a/b/c/','a/b/c','\\a\\b\\c','\\a\\b\\c\\','a\\b\\c','a/b/../../a/b/c/','a/b/../../a/b/c'] for a in b: print (a, a.rstrip("\\" if a.count("/") == 0 else '/').split("\\" if a.count("/") == 0 else '/')[-1]) 

Может быть, только мое все в одном решении без важных новых (см. Временный файл для создания временных файлов: D)

 import tempfile abc = tempfile.NamedTemporaryFile(dir='/tmp/') abc.name abc.name.replace("/", " ").split()[-1] 

Получение значений abc.name будет такой же строкой: '/tmp/tmpks5oksk7' Поэтому я могу заменить / на пробел .replace("/", " ") а затем вызвать split() . Это вернет список, и я получу последний элемент списка с [-1]

Не нужно импортировать какой-либо модуль.

с наилучшими пожеланиями

4k3nd0

Это решение только для регулярных выражений, которое, похоже, работает с любым пути ОС на любой ОС.

Никакой другой модуль не нужен, и не требуется предварительная обработка:

 import re def extract_basename(path): """Extracts basename of a given path. Should Work with any OS Path on any OS""" basename = re.search(r'[^\\/]+(?=[\\/]?$)', path) if basename: return basename.group(0) paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c', 'a/b/../../a/b/c/', 'a/b/../../a/b/c'] print [extract_basename(path) for path in paths] # ['c', 'c', 'c', 'c', 'c', 'c', 'c'] extra_paths = ['C:\\', 'alone', '/a/space in filename', 'C:\\multi\nline'] print [extract_basename(path) for path in extra_paths] # ['C:', 'alone', 'space in filename', 'multi\nline'] 

Регулярное выражение можно проверить здесь .

Для полноты, вот решение pathlib для python 3.2+:

 >>> from pathlib import PureWindowsPath >>> paths = ['a/b/c/', 'a/b/c', '\\a\\b\\c', '\\a\\b\\c\\', 'a\\b\\c', ... 'a/b/../../a/b/c/', 'a/b/../../a/b/c'] >>> [PureWindowsPath(path).name for path in paths] ['c', 'c', 'c', 'c', 'c', 'c', 'c'] 

Это работает как для Windows, так и для Linux.

 filename = path[path.rfind('/')+1:] 
  • Как я могу программным образом проверить статус очереди задач в Google Appengine?
  • Python NotImplemented constant
  • Отдельные слова в списке, а затем печать позиций этих слов
  • Способ доступа к файлам ресурсов в python
  • Создать класс-оболочку для вызова функции pre и post вокруг существующих функций?
  • Разница между рейзом Exception, «foo» и raise Exception («foo»)?
  • Ubuntu Chrome: как читать cookie из скрипта python
  • объединение двух строковых переменных
  • Python - лучший язык программирования в мире.