python - 从路径中提取文件名,无论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
Jerome asked 2019-01-10T15:17:43Z
14个解决方案
783 votes
实际上,有一个功能可以准确地返回您想要的功能
print(os.path.basename(your_path))
stranac answered 2019-01-10T15:18:42Z
526 votes
使用r'a/b\c'或b\c作为其他建议将不适用于所有情况:如果您在Linux上运行脚本并尝试处理经典的Windows样式路径,它将失败。
Windows路径可以使用反斜杠或正斜杠作为路径分隔符。 因此,r'a/b\c'模块(在Windows上运行时相当于os.path)将适用于所有平台上的所有(1)路径。
import ntpath
ntpath.basename("a/b/c")
当然,如果文件以斜杠结尾,则basename将为空,因此请创建自己的函数来处理它:
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'始终引用a文件夹中的文件b\c,而在Windows上,它始终引用b文件夹b子文件夹中的c文件。 因此,当在路径中使用向前和向后斜杠时,您需要知道相关平台才能正确解释它。 在实践中,通常可以安全地假设它是一个Windows路径,因为Linux文件名中很少使用反斜杠,但在编写代码时请记住这一点,这样就不会产生意外的安全漏洞。
Lauritz V. Thaulow answered 2019-01-10T15:18:19Z
147 votes
os.path.split这样是你正在寻找的功能
head, tail = os.path.split("/tmp/d/a.dat")
>>> print(tail)
a.dat
>>> print(head)
/tmp/d
Jakob Bowyer answered 2019-01-10T15:19:04Z
31 votes
import os
head, tail = os.path.split(p)
print tail
假设p是输入字符串,tail就是你想要的。
有关详细信息,请参阅python os模块文档
number5 answered 2019-01-10T15:19:35Z
18 votes
在python 3中
>>> from pathlib import Path
>>> Path("/tmp/d/a.dat").name
'a.dat'
Kishan B answered 2019-01-10T15:19:57Z
9 votes
在您的示例中,您还需要从右侧右侧删除斜杠以返回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'
更新:我认为lazyr提供了正确的答案。 我的代码不适用于unix系统上的类似Windows的路径,也不适用于Windows系统上的类似unix的路径。
Ski answered 2019-01-10T15:20:36Z
6 votes
fname = str("C:\Windows\paint.exe").split('\\')[-1:][0]
这将返回:paint.exe
更改有关路径或操作系统的拆分功能的sep值。
Eslam Hamouda answered 2019-01-10T15:21:06Z
6 votes
这适用于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']
Csabka answered 2019-01-10T15:21:30Z
4 votes
我从未见过双背路径,它们是否存在? python模块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))
PythoNic answered 2019-01-10T15:21:53Z
3 votes
Windows分隔符可以是Unix文件名或Windows路径。 Unix分隔符只能存在于Unix路径中。 Unix分隔符的存在表示非Windows路径。
以下将通过OS特定分隔符剥离(剪切尾随分隔符),然后拆分并返回最右边的值。 它很难看,但基于上面的假设很简单。 如果假设不正确,请更新,我将更新此响应以匹配更准确的条件。
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])
dusc2don answered 2019-01-10T15:22:30Z
3 votes
这是一个仅使用正则表达式的解决方案,它似乎适用于任何操作系统上的任何操作系统路径。
不需要其他模块,也不需要预处理:
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']
可以在这里测试正则表达式。
Eric Duminil answered 2019-01-10T15:23:08Z
2 votes
也许只是我的所有在一个解决方案中没有重要的一些新的(关于创建临时文件的临时文件:D)
import tempfile
abc = tempfile.NamedTemporaryFile(dir='/tmp/')
abc.name
abc.name.replace("/", " ").split()[-1]
获得abc.name的值将是这样的字符串:'/tmp/tmpks5oksk7'所以我可以用空格.replace("/", " ")替换/,然后调用split().这将返回一个列表,我得到了[-1]列表的最后一个元素
无需导入任何模块。
最好的祝福
4k3nd0
Akendo answered 2019-01-10T15:24:00Z
1 votes
为了完整起见,这里是针对python 3.2+的pathlib解决方案:
>>> 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。
Morgoth answered 2019-01-10T15:24:29Z
-5 votes
filename = path[path.rfind('/')+1:]
Qiyun answered 2019-01-10T15:24:44Z