从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.splitos.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:]