如何在Python中将dos路径拆分为其组件

如何在Python中将dos路径拆分为其组件,python,Python,我有一个表示dos路径的字符串变量,例如: var=“d:\stuff\morestuff\furthedown\THEFILE.txt” 我想将此字符串拆分为: [“d”,“stuff”,“morestuff”,“furthedown”,“THEFILE.txt”] 我尝试过使用split()和replace()但是它们要么只处理第一个反斜杠,要么在字符串中插入十六进制数 我需要以某种方式将这个字符串变量转换为原始字符串,以便能够解析它 最好的方法是什么 我还应该补充一点,var的内容,即我试

我有一个表示dos路径的字符串变量,例如:

var=“d:\stuff\morestuff\furthedown\THEFILE.txt”

我想将此字符串拆分为:

[“d”,“stuff”,“morestuff”,“furthedown”,“THEFILE.txt”]

我尝试过使用
split()
replace()
但是它们要么只处理第一个反斜杠,要么在字符串中插入十六进制数

我需要以某种方式将这个字符串变量转换为原始字符串,以便能够解析它

最好的方法是什么

我还应该补充一点,
var
的内容,即我试图解析的路径,实际上是命令行查询的返回值。我自己生成的不是路径数据。它存储在一个文件中,并且命令行工具不会逃避反斜杠。

它对我有用:

>>> a=r"d:\stuff\morestuff\furtherdown\THEFILE.txt"
>>> a.split("\\")
['d:', 'stuff', 'morestuff', 'furtherdown', 'THEFILE.txt']
当然,您可能还需要从第一个组件中去掉冒号,但保留冒号可以重新组装路径


r
修饰符将字符串文字标记为“raw”;请注意嵌入的反斜杠是如何不加倍的。

使用
ntpath.split()
这里的问题首先从如何创建字符串开始

a = "d:\stuff\morestuff\furtherdown\THEFILE.txt"
通过这种方式,Python尝试对以下情况进行特殊处理:
\s
\m
\f
\T
。在您的情况下,
\f
被视为一个表单提要(0x0C),而其他反斜杠被正确处理。您需要执行以下操作之一:

b = "d:\\stuff\\morestuff\\furtherdown\\THEFILE.txt"      # doubled backslashes
c = r"d:\stuff\morestuff\furtherdown\THEFILE.txt"         # raw string, no doubling necessary

然后,一旦您拆分其中任何一个,您将得到想要的结果。

关于
mypath.split(\\”
的内容最好用
mypath.split(os.sep)
表示
sep
是特定平台的路径分隔符(例如,Windows的
\
、Unix的
/
等),Python构建知道使用哪个平台。如果您使用
sep
,那么您的代码将是平台不可知的。

我已经被人们编写他们自己的路径篡改函数并出错的情况折磨了很多次。空格、斜杠、反斜杠、冒号——造成混淆的可能性并非无穷无尽,但不管怎样,还是很容易出错。因此,我坚持使用
os.path
,并在此基础上推荐它

(然而,通往美德的道路并不是最容易走的,许多人在发现这一点时,都会倾向于走一条通往诅咒的滑路。直到有一天一切都崩溃了,他们才意识到,他们——或者更可能的是,其他人——必须弄清楚为什么一切都出了问题,结果是有人犯了错误。)我喜欢把斜杠和反斜杠混在一起——有人建议答案是“不要那样做”。不要成为这些人中的任何一个。除了那些把斜杠和反斜杠混在一起的人——如果你愿意,你可以成为他们。)

您可以按如下方式获取驱动器和path+文件:

drive, path_and_file = os.path.splitdrive(path)
获取路径和文件:

path, file = os.path.split(path_and_file)
获取单个文件夹名称并不是特别方便,但这是一种诚实的中等程度的不适感,增加了以后找到真正有效的东西的乐趣:

folders = []
while 1:
    path, folder = os.path.split(path)

    if folder != "":
        folders.append(folder)
    elif path != "":
        folders.append(path)

        break

folders.reverse()

(如果路径最初是绝对路径,则会在文件夹的开头弹出一个
“\”
。如果不想这样做,可能会丢失一些代码。)

就像其他人解释的一样-您的问题源于使用
\
,即字符串literal/constant.oth中的转义字符,如果您从另一个源(从文件、控制台读取或由操作系统函数返回)获得该文件路径字符串,则在“\\”或r“\”上拆分不会出现问题

正如其他人所建议的,如果您想在程序文本中使用
\
,您必须复制它
\
,或者整个文本必须以
r
作为前缀,就像
r'lite\ral'
r“lite\ral”
那样,以避免解析器将
\
r
转换为CR(回车)性格

还有一种方法-只是不要在代码中使用反斜杠
\
路径名!因为上个世纪Windows可以识别并使用使用正斜杠作为目录分隔符的路径名
/
!不知何故,没有多少人知道这一点。但它可以工作:

>>> var = "d:/stuff/morestuff/furtherdown/THEFILE.txt"
>>> var.split('/')
['d:', 'stuff', 'morestuff', 'furtherdown', 'THEFILE.txt']

顺便说一句,这将使您的代码在Unix、Windows和Mac上工作…因为它们都使用
/
作为目录分隔符…即使您不想使用模块
os

的预定义常量,假设您有一个包含以下内容的文件
filedata.txt

d:\stuff\morestuff\furtherdown\THEFILE.txt
d:\otherstuff\something\otherfile.txt
您可以读取和拆分文件路径:

>>> for i in open("filedata.txt").readlines():
...     print i.strip().split("\\")
... 
['d:', 'stuff', 'morestuff', 'furtherdown', 'THEFILE.txt']
['d:', 'otherstuff', 'something', 'otherfile.txt']

由于它使用了os.path.basename函数,因此我使用了以下命令:它不会向返回的列表中添加任何斜杠。它也可以与任何平台的斜杠一起使用:即窗口的
\\\\\\\
unix的
/
。此外,它不会添加windows用于服务器路径:)

因此:

\\\\\\\server\\\\folder1\\\\folder2\\\\folder3\\\\folder4
你会得到:

['server','folder1','folder2','folder3','folder4']

您可以简单地使用最具Python风格的方法(IMHO):

这将给你:

['d:', 'stuff', 'morestuff', 'furtherdown', 'THEFILE.txt']
这里的线索是使用
os.sep
而不是
'\\'
'/'
,因为这使它独立于系统

要从驱动器号中删除冒号(尽管我看不出您希望这样做的任何原因),您可以编写:

path_list[0] = path_list[0][0]

对于一个更简洁的解决方案,考虑以下内容:

def split_path(p):
    a,b = os.path.split(p)
    return (split_path(a) if len(a) and len(b) else []) + [b]

实际上,我无法给出一个真正的答案(因为我来这里是希望自己能找到一个答案),但对我来说,不同方法的数量和所有提到的注意事项是最可靠的指标,表明Python的os.path模块迫切需要将其作为一个内置函数。

import os
path = os.path.normpath(path)
path.split(os.sep)
首先,将路径字符串规范化为操作系统的适当字符串。然后,
os.sep
必须可以安全地用作字符串函数拆分中的分隔符。

def split_path(p):
    a,b = os.path.split(p)
    return (split_path(a) if len(a) and len(b) else []) + [b]
import os
path = os.path.normpath(path)
path.split(os.sep)
import re    
var = "d:\stuff\morestuff\furtherdown\THEFILE.txt"
re.split( r'[\\/]', var )
['d:', 'stuff', 'morestuff', 'furtherdown', 'THEFILE.txt']
import re    
var = "/var/stuff/morestuff/furtherdown/THEFILE.txt"
result = re.split( r'[\\/]', var )
filter( None, result )
['var', 'stuff', 'morestuff', 'furtherdown', 'THEFILE.txt']
def components(path):
    ret = []
    while len(path) > 0:
        path, crust = split(path)
        ret.insert(0, crust)
    return ret
def split(path):
    (drive, head) = os.path.splitdrive(path)
    while (head != os.sep):
        (head, tail) = os.path.split(head)
        yield tail
>>> print([x for x in split(os.path.normpath('/path/to/filename'))])
['filename', 'to', 'path']
>>> from pathlib import Path
>>> Path('C:/path/to/file.txt').parts
('C:\\', 'path', 'to', 'file.txt')
>>> Path(r'C:\path\to\file.txt').parts
('C:\\', 'path', 'to', 'file.txt')
>>> from pathlib import PurePosixPath, PureWindowsPath
>>> PurePosixPath('/path/to/file.txt').parts
('/', 'path', 'to', 'file.txt')
>>> PureWindowsPath(r'C:\path\to\file.txt').parts
('C:\\', 'path', 'to', 'file.txt')
>>> PureWindowsPath(r'\\host\share\path\to\file.txt').parts
('\\\\host\\share\\', 'path', 'to', 'file.txt')
import os
def parts(path):
    p,f = os.path.split(path)
    return parts(p) + [f] if f else [p]
>>> for path in [
...         r'd:\stuff\morestuff\furtherdown\THEFILE.txt',
...         '/path/to/file.txt',
...         'relative/path/to/file.txt',
...         r'C:\path\to\file.txt',
...         r'\\host\share\path\to\file.txt',
...     ]:
...     print parts(path), os.path.join(*parts(path))
... 
['d:\\', 'stuff', 'morestuff', 'furtherdown', 'THEFILE.txt'] d:\stuff\morestuff\furtherdown\THEFILE.txt
['/', 'path', 'to', 'file.txt'] /path\to\file.txt
['', 'relative', 'path', 'to', 'file.txt'] relative\path\to\file.txt
['C:\\', 'path', 'to', 'file.txt'] C:\path\to\file.txt
['\\\\', 'host', 'share', 'path', 'to', 'file.txt'] \\host\share\path\to\file.txt
import os
def parts(path):
    p,f = os.path.split(path)
    return parts(p) + [f] if f else [os.path.splitdrive(p)]

[('d:', '\\'), 'stuff', 'morestuff', 'furtherdown', 'THEFILE.txt']
[('', '/'), 'path', 'to', 'file.txt']
[('', ''), 'relative', 'path', 'to', 'file.txt']
[('C:', '\\'), 'path', 'to', 'file.txt']
[('', '\\\\'), 'host', 'share', 'path', 'to', 'file.txt']
import os

def split_path(path):
    head = os.path.dirname(path)
    tail = os.path.basename(path)
    if head == os.path.dirname(head):
        return [tail]
    return split_path(head) + [tail]
def parts(path):
    p,f = os.path.split(os.path.normpath(path))
    return parts(p) + [f] if f and p else [p] if p else []
from os import path as os_path
def split_path_iter(string, lst):
    head, tail = os_path.split(string)
    if head == '':
        return [string] + lst
    else:
        return split_path_iter(head, [tail] + lst)

def split_path(string):
    return split_path_iter(string, [])
def split_path(string):
    head, tail = os_path.split(string)
    if head == '':
        return [string]
    else:
        return split_path(head) + [tail]
import os

a = '/media//max/Data/'

def splitall(path):
    # https://www.oreilly.com/library/view/python-cookbook/0596001673/ch04s16.html
    allparts = []
    while 1:
        parts = os.path.split(path)
        if parts[0] == path:  # sentinel for absolute paths
            allparts.insert(0, parts[0])
            break
        elif parts[1] == path: # sentinel for relative paths
            allparts.insert(0, parts[1])
            break
        else:
            path = parts[0]
            allparts.insert(0, parts[1])
    return allparts

x = splitall(a)
print(x)

z = os.path.join(*x)
print(z)
['/', 'media', 'max', 'Data', '']
/media/max/Data/