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

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

我想把这个字符串分成:

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

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

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

最好的方法是什么?

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


当前回答

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

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

其他回答

在Python >=3.4中,这变得简单得多。您现在可以使用pathlib.Path.parts来获取路径的所有部分。

例子:

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

在Python 3的Windows安装上,这将假设您使用的是Windows路径,而在*nix上,它将假设您使用的是posix路径。这通常是你想要的,但如果不是,你可以使用类pathlib。PurePosixPath或pathlib。PureWindowsPath:

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

编辑: 还有一个python 2的反向端口:pathlib2

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

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)

首先,将路径字符串规范化为适合操作系统的字符串。那么操作系统。Sep在字符串函数split中用作分隔符必须是安全的。

就像其他人解释的那样-你的问题源于使用\,这是字符串字面量/常量中的转义字符。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的预定义常量。

递归是为了好玩。

这不是最优雅的回答,但应该适用于任何地方:

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]