从path中提取文件名,不pipe是什么os /path格式
无论操作系统或path格式如何,我可以使用哪个Python库从path提取文件名?
例如,我想所有这些path返回我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
在其他情况下使用os.path.split
或os.path.basename
将无法在所有情况下工作:如果您在Linux上运行脚本并尝试处理经典的Windows样式path,则将失败。
Windowspath可以使用反斜线或正斜杠作为path分隔符。 因此, ntpath
模块(在windows上运行时相当于os.path)将适用于所有平台上的所有(1)path。
import ntpath ntpath.basename("a/b/c")
当然,如果文件以斜线结尾,基本名称将是空的,所以请自行设置函数来处理它:
def path_leaf(path): head, tail = ntpath.split(path) return tail or ntpath.basename(head)
validation:
>>> 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
,而在Windows中,它总是指文件夹b
子文件夹中的c
文件。 因此,当在一个path中使用正斜杠和反斜杠时,您需要知道关联的平台能够正确解释它。 实际上,假设它是一个Windowspath通常是安全的,因为在Linux文件名中很less使用反斜杠,但是在编写代码时请记住这一点,以免造成意外的安全漏洞。
其实,有一个function ,返回到你想要的
print os.path.basename(your_path)
os.path.split是你正在寻找的function
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是inputstring,尾巴就是你想要的。
有关详细信息,请参阅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'
更新:我认为lazyr
已经提供了正确的答案。 我的代码不能在unix系统上使用类似windows的path,而在windows系统上使用unix类似的path。
fname = str("C:\Windows\paint.exe").split('\\')[-1:][0]
这将返回: paint.exe
更改有关您的path或操作系统的拆分函数的sep值。
这是工作在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模块os
的内置function失败了。 所有其他的工作,也是你用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文件名或Windowspath。 Unix分隔符只能存在于Unixpath中。 Unix分隔符的存在表示非Windowspath。
以下操作将通过操作系统特定的分隔符去除(剪切尾随分隔符),然后分割并返回最右边的值。 这是丑陋的,但简单的基于上面的假设。 如果假设不正确,请更新,我将更新此响应以匹配更准确的条件。
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])
也许只是我所有在一个解决scheme中没有重要的一些新的(关于创build临时文件的临时文件:D)
import tempfile abc = tempfile.NamedTemporaryFile(dir='/tmp/') abc.name abc.name.replace("/", " ").split()[-1]
获取abc.name
的值将是一个像这样的string: '/tmp/tmpks5oksk7'
所以我可以用空格replace/
.replace("/", " ")
,然后调用split()
。 这将返回一个列表,我得到列表的最后一个元素与[-1]
不需要导入任何模块。
最好的祝福
4k3nd0
这是一个仅适用于正则expression式的解决scheme,似乎可以在任何操作系统上使用任何操作系统path。
不需要其他模块,也不需要预处理:
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']
正则expression式可以在这里testing。
为了完整起见,下面是python 3.2+的pathlib
解决scheme:
>>> 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:]