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

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

我想把这个字符串分成:

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

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

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

最好的方法是什么?

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


当前回答

这里的问题首先要从如何创建字符串开始。

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

一旦你把它们分开,你就会得到你想要的结果。

其他回答

你可以简单地使用最python化的方法(IMHO):

import os

your_path = r"d:\stuff\morestuff\furtherdown\THEFILE.txt"
path_list = your_path.split(os.sep)
print path_list

这将给你:

['d:', 'stuff', 'morestuff', 'furtherdown', 'THEFILE.txt']

这里的线索是使用操作系统。Sep而不是“\\”或“/”,因为这使得它与系统无关。

要从驱动器号中删除冒号(尽管我看不出你为什么要这样做),你可以这样写:

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

你可以递归的os。path。拆分字符串

import os
def parts(path):
    p,f = os.path.split(path)
    return parts(p) + [f] if f else [p]

针对一些路径字符串进行测试,并使用os.path.join重新组装路径

>>> 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

列表的第一个元素可能需要区别对待,这取决于您想如何处理驱动器号、UNC路径以及绝对路径和相对路径。将最后一个[p]更改为[os.path.splitdrive(p)],通过将驱动器号和目录根分解为一个元组来强制解决这个问题。

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']

编辑:我意识到这个答案与上面user1556435给出的答案非常相似。我留下我的答案,因为路径的驱动器组件的处理是不同的。

就像其他人解释的那样-你的问题源于使用\,这是字符串字面量/常量中的转义字符。OTOH,如果你有文件路径字符串从其他来源(从文件读取,控制台或由操作系统函数返回)-不会有问题分裂'\\'或r'\'。

就像其他人建议的那样,如果你想在程序文字中使用\,你必须复制它\\或者整个文字必须以r为前缀,比如r'lite\ral'或r"lite\ral",以避免解析器将\和r转换为CR(回车)字符。

还有一种方法——不要在代码中使用反斜杠\ pathnames !自上个世纪以来,Windows可以很好地识别使用正斜杠作为目录分隔符的路径名/!不知何故,没有多少人知道…但它是有效的:

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

顺便说一下,这将使您的代码在Unix, Windows和Mac上工作…因为它们都使用/作为目录分隔符…即使你不想使用模块os的预定义常量。

我曾多次被那些编写自己的路径篡改函数并出错的人所困扰。空格、斜杠、反斜杠、冒号——造成混淆的可能性不是无穷尽的,但无论如何都很容易犯错误。所以我很坚持使用操作系统。路径,并在此基础上推荐它。

(However, the path to virtue is not the one most easily taken, and many people when finding this are tempted to take a slippery path straight to damnation. They won't realise until one day everything falls to pieces, and they -- or, more likely, somebody else -- has to work out why everything has gone wrong, and it turns out somebody made a filename that mixes slashes and backslashes -- and some person suggests that the answer is "not to do that". Don't be any of these people. Except for the one who mixed up slashes and backslashes -- you could be them if you like.)

你可以像这样获得驱动器和路径+文件:

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()

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

下面的代码行可以处理:

C:/路径/路径 C://path//path C:\路径\路径 C:\路径\路径

Path = re.split(r'[///\]', Path)