Вот решение, предназначенное только для регулярных выражений, которое, похоже, работает с любым путем к ОС в любой ОС.
Никаких других модулей не требуется, и предварительная обработка не требуется:
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']
Обновление:
Если вам нужно только потенциальное имя файла, если оно присутствует (т. Е. /a/b/
- это каталог, а значит c:\windows\
), измените регулярное выражение на: r'[^\\/]+(?![\\/])$'
.Для "regex challengeed" это меняет положительный прогноз вперед для своего рода слеш на отрицательный прогноз вперед, в результате чего имена путей, оканчивающиеся на slash , ничего не возвращают вместо последнегоподкаталог в пути.Конечно, нет никакой гарантии, что имя файла потенциальная на самом деле ссылается на файл, и для этого потребуется использовать os.path.is_dir()
или os.path.is_file()
.
Это будет соответствовать следующему:
/a/b/c/ # nothing, pathname ends with the dir 'c'
c:\windows\ # nothing, pathname ends with the dir 'windows'
c:hello.txt # matches potential filename 'hello.txt'
~it_s_me/.bashrc # matches potential filename '.bashrc'
c:\windows\system32 # matches potential filename 'system32', except
# that is obviously a dir. os.path.is_dir()
# should be used to tell us for sure
Регулярное выражение можно проверить здесь .