J'ai une variable de chaîne qui représente un chemin dos, par exemple:
var = "d:\stuff\morestuff\furtherdown\THEFILE.txt"
Je veux diviser cette chaîne en:
[ "d", "stuff", "morestuff", "furtherdown", "THEFILE.txt" ]
J'ai essayé d'utiliser split()
et replace()
mais ils ne traitent que la première barre oblique inverse ou ils insèrent des nombres hexadécimaux dans la chaîne.
J'ai besoin de convertir cette variable de chaîne en une chaîne brute afin de pouvoir l'analyser.
Quelle est la meilleure façon de procéder?
Je devrais également ajouter que le contenu de var
ie le chemin que j'essaie d'analyser, est en fait la valeur de retour d'une requête de ligne de commande. Ce ne sont pas des données de chemin que je génère moi-même. Il est stocké dans un fichier et l'outil de ligne de commande n'échappera pas aux barres obliques inverses.
os.path.split
ne fonctionne pas pour vous car vous n'échappez pas correctement à cette chaîne.r"d:\stuff\morestuff\furtherdown\THEFILE.txt"
pour éviter que des choses comme\s
une mauvaise interprétation.Réponses:
J'ai été mordu de nombreuses fois par des gens qui écrivent leurs propres fonctions de violon et se trompent. Espaces, barres obliques, barres obliques inverses, deux-points - les possibilités de confusion ne sont pas infinies, mais des erreurs sont faciles de toute façon. Je suis donc très perspicace pour l'utilisation de
os.path
, et je le recommande sur cette base.(Cependant, le chemin de la vertu n'est pas celui qui est le plus facile à emprunter, et beaucoup de gens, lorsqu'ils le trouvent, sont tentés de prendre un chemin glissant directement vers la damnation. Ils ne réaliseront pas avant qu'un jour tout tombe en morceaux, et ils - ou , plus probablement, quelqu'un d'autre - doit trouver pourquoi tout a mal tourné, et il s'avère que quelqu'un a créé un nom de fichier qui mélange des barres obliques inverses et des barres obliques inverses - et quelqu'un suggère que la réponse est "ne pas faire cela". Don ' t être l'une de ces personnes. À l'exception de celle qui a mélangé des barres obliques inverses et des barres obliques inverses - vous pourriez être elles si vous le souhaitez.)
Vous pouvez obtenir le lecteur et le chemin + le fichier comme ceci:
Récupérez le chemin et le fichier:
Obtenir les noms de dossiers individuels n'est pas particulièrement pratique, mais c'est le genre d'inconfort moyen honnête qui augmente le plaisir de trouver plus tard quelque chose qui fonctionne bien:
(Cela apparaît
"\"
au début defolders
si le chemin était à l'origine absolu. Vous pourriez perdre un peu de code si vous ne le vouliez pas.)la source
if path.endswith("/"):
etpath = path[:-1]
.je ferais
Commencez par normaliser la chaîne de chemin en une chaîne appropriée pour le système d'exploitation. Ensuite, il
os.sep
doit être sûr de l'utiliser comme délimiteur dans la fonction de chaîne fractionnée.la source
os.path.normpath(a_path).split(os.path.sep)
os.path.normpath(path).lstrip(os.path.sep).split(os.path.sep)
normpath
reconnaîtra la barre oblique comme séparateur. Sous Linux,normpath
supposera simplement que vous avez un répertoire appelé\1\2
et un fichier ou un répertoire à l'intérieur appelé3
.Vous pouvez simplement utiliser l'approche la plus pythonique (IMHO):
Ce qui vous donnera:
L'indice ici est d'utiliser à la
os.sep
place de'\\'
ou'/'
, car cela le rend indépendant du système.Pour supprimer deux points de la lettre de lecteur (bien que je ne vois aucune raison pour laquelle vous voudriez le faire), vous pouvez écrire:
la source
some times
. D'autres fois (sur Windows au moins), vous trouverez des chemins qui ressemblent àfolder\folder2\folder3/file.txt
. Il est préférable de normaliser d'abord (os.path.normpath) le chemin, puis de le diviser./foo//bar
). Voir la réponse de Tompa pour une solution plus robuste.En Python> = 3.4, cela est devenu beaucoup plus simple. Vous pouvez maintenant utiliser
pathlib.Path.parts
pour obtenir toutes les parties d'un chemin.Exemple:
Sur une installation Windows de Python 3, cela supposera que vous travaillez avec des chemins Windows, et sur * nix, cela supposera que vous travaillez avec des chemins posix. C'est généralement ce que vous voulez, mais si ce n'est pas le cas, vous pouvez utiliser les classes
pathlib.PurePosixPath
oupathlib.PureWindowsPath
selon vos besoins:Edit: Il existe également un backport vers python 2 disponible: pathlib2
la source
Le problème ici commence par la façon dont vous créez la chaîne en premier lieu.
Fait de cette façon, Python essaie de cas particulier celles - ci:
\s
,\m
,\f
et\T
. Dans votre cas,\f
est traité comme un saut de page (0x0C) tandis que les autres barres obliques inverses sont gérées correctement. Voici ce que vous devez faire:Ensuite, une fois que vous avez divisé l'un ou l'autre, vous obtiendrez le résultat souhaité.
la source
split()
oureplace()
travailler pour une raison quelconque - j'ai continué à obtenir des valeurs hexadécimales. Vous avez raison cependant, je pense que j'aboyais le mauvais arbre avec l'idée de chaîne brute - je pense que je n'utilisais simplementsplit()
pas correctement. Parce que j'ai essayé certaines de ces solutions en utilisantsplit()
et elles fonctionnent pour moi maintenant.Pour une solution un peu plus concise, considérez ce qui suit:
la source
/
. En outre, vous donne une chaîne vide au début de la liste si votre chemin commence par/
Je ne peux pas réellement apporter une vraie réponse à celle-ci (car je suis venu ici en espérant en trouver une moi-même), mais pour moi, le nombre d'approches différentes et toutes les mises en garde mentionnées est l'indicateur le plus sûr que le module os.path de Python en a désespérément besoin. comme fonction intégrée.
la source
La manière fonctionnelle, avec un générateur .
En action:
la source
Ça marche pour moi:
Bien sûr, vous devrez peut-être également supprimer les deux points du premier composant, mais le garder permet de réassembler le chemin.
Le
r
modificateur marque la chaîne littérale comme "brute"; remarquez que les contre-obliques intégrées ne sont pas doublées.la source
r
devant votre chaîne, à quoi cela fait-il référence?\
caractères. Il est utile d'utiliser chaque fois que vous faites des chemins.os.path.split
etos.pathsep
, étant donné que ces deux éléments sont beaucoup plus portables que ce que vous avez écrit. Cela n'a peut-être pas d'importance pour OP maintenant, mais ce sera le cas quand il écrit quelque chose qui doit déplacer les plates-formes.Le truc à propos de
mypath.split("\\")
serait mieux exprimé commemypath.split(os.sep)
.sep
est le séparateur de chemin pour votre plate-forme particulière (par exemple,\
pour Windows,/
pour Unix, etc.), et la construction Python sait laquelle utiliser. Si vous utilisezsep
, votre code sera indépendant de la plate-forme.la source
os.path.split
. Vous voulez faire attentionos.pathsep
, car c'est:
sur ma version de Python sous OS X (etos.path.split
gère correctement/
).os.sep
nonos.pathsep
. Suivez la sagesse de laos.sep
documentation: notez que cela ne suffit pas pour pouvoir analyser ou concaténer les chemins d'accès - utilisez os.path.split () et os.path.join ().re.split () peut aider un peu plus que string.split ()
Si vous souhaitez également prendre en charge les chemins Linux et Mac, ajoutez simplement un filtre (Aucun, résultat), afin de supprimer les "" indésirables de split () puisque leurs chemins commencent par "/" ou "//". par exemple '// mount / ...' ou '/ var / tmp /'
la source
Vous pouvez récursivement
os.path.split
la chaîneTester cela par rapport à certaines chaînes de chemin et réassembler le chemin avec
os.path.join
Le premier élément de la liste peut devoir être traité différemment selon la manière dont vous souhaitez traiter les lettres de lecteur, les chemins UNC et les chemins absolus et relatifs. Changer le dernier
[p]
pour[os.path.splitdrive(p)]
forcer le problème en divisant la lettre de lecteur et la racine du répertoire en un tuple.Edit: J'ai réalisé que cette réponse est très similaire à celle donnée ci-dessus par user1556435 . Je laisse ma réponse car la gestion du composant d'entraînement du chemin est différente.
la source
Tout comme d'autres l'ont expliqué - votre problème provenait de l'utilisation
\
, qui est un caractère d'échappement dans une chaîne littérale / constante. OTOH, si vous aviez cette chaîne de chemin de fichier d'une autre source (lue à partir du fichier, de la console ou renvoyée par la fonction os) - il n'y aurait pas eu de problème de division sur '\\' ou r '\'.Et tout comme d'autres l'ont suggéré, si vous voulez utiliser
\
dans le littéral du programme, vous devez soit le dupliquer,\\
soit tout le littéral doit être préfixé parr
, comme çar'lite\ral'
our"lite\ral"
pour éviter que l'analyseur ne convertisse cela\
etr
en caractère CR (retour chariot).Il existe cependant un autre moyen: n'utilisez simplement pas de
\
noms de chemin de barre oblique inverse dans votre code! Depuis le siècle dernier, Windows reconnaît et fonctionne très bien avec les chemins d'accès qui utilisent la barre oblique comme séparateur de répertoire/
! Peu de gens le savent, mais cela fonctionne:Cela permettra à votre code de fonctionner sous Unix, Windows et Mac ... car ils l'utilisent tous
/
comme séparateur de répertoire ... même si vous ne voulez pas utiliser les constantes prédéfinies du moduleos
.la source
var = var.replace('\\','/')
- remplacez \ par / et continuez à travailler avec des barres obliques uniquement :)Supposons que vous ayez un fichier
filedata.txt
avec du contenu:Vous pouvez lire et diviser les chemins de fichiers:
la source
J'utilise ce qui suit car puisqu'il utilise la fonction os.path.basename, il n'ajoute aucune barre oblique à la liste renvoyée. Il fonctionne également avec les barres obliques de n'importe quelle plate-forme: c'est-à-dire \\ de fenêtre ou / d'Unix. Et de plus, il n'ajoute pas le \\\\ que Windows utilise pour les chemins du serveur :)
Donc pour '\\\\ server \\ folder1 \\ folder2 \\ folder3 \\ folder4'
vous obtenez
['serveur', 'dossier1', 'dossier2', 'dossier3', 'dossier4']
la source
os.path.join()
devrait renvoyer la chaîne d'origine. Je dirais que la sortie correcte pour votre exemple d'entrée est[r'\\','server','folder1','folder2','folder3','folder4']
. Ie queos.path.split()
fait.Je ne suis pas vraiment sûr que cela réponde entièrement à la question, mais je me suis amusé à écrire cette petite fonction qui garde une pile, s'en tient aux manipulations basées sur os.path et renvoie la liste / pile d'éléments.
la source
La ligne de code ci-dessous peut gérer:
path = re.split (r '[/// \]', chemin)
la source
Un récursif pour le plaisir.
Pas la réponse la plus élégante, mais devrait fonctionner partout:
la source
utilisation
ntpath.split()
la source
d:\\stuff
,morestuff\x0curtherdown\thefile.mux
)d:\\stuff, morestuff\x0curtherdown\thefile.mux
'\x0c'
est le caractère d'alimentation de formulaire. La manière de créer le caractère de saut de formulaire est «\ f». Si vous voulez vraiment la chaîne littérale '\ f', vous avez deux options:'\\f'
our'\f'
.