Tengo una variable de cadena que representa una ruta de dos por ejemplo:
var = "d:\stuff\morestuff\furtherdown\THEFILE.txt"
Quiero dividir esta cadena en:
[ "d", "stuff", "morestuff", "furtherdown", "THEFILE.txt" ]
He intentado usar split()
y replace()
pero solo procesan la primera barra diagonal inversa o insertan números hexadecimales en la cadena.
Necesito convertir esta variable de cadena en una cadena sin procesar de alguna manera para poder analizarla.
¿Cuál es la mejor manera de hacer esto?
También debo agregar que el contenido de, var
es decir, la ruta que estoy tratando de analizar, es en realidad el valor de retorno de una consulta de línea de comando. No son datos de ruta los que yo mismo genero. Está almacenado en un archivo, y la herramienta de línea de comando no va a escapar de las barras diagonales inversas.
os.path.split
no funciona para usted porque no está escapando de esa cadena correctamente.r"d:\stuff\morestuff\furtherdown\THEFILE.txt"
para evitar cosas como\s
ser malinterpretado.Respuestas:
He sido mordido muchas veces por personas que escriben sus propias funciones de violín y se equivocan. Espacios, barras, barras invertidas, dos puntos: las posibilidades de confusión no son infinitas, pero de todos modos los errores se cometen fácilmente. Por lo tanto, soy muy exigente con el uso
os.path
y lo recomiendo sobre esa base.(Sin embargo, el camino hacia la virtud no es el más fácil de tomar, y muchas personas al encontrar esto se sienten tentadas a tomar un camino resbaladizo directo a la condenación. No se darán cuenta hasta que un día todo se haga pedazos, y ellos ... o , lo más probable es que alguien más tenga que averiguar por qué todo salió mal y resulta que alguien creó un nombre de archivo que mezcla barras y barras diagonales inversas, y alguien sugiere que la respuesta es "no hacer eso". t sea cualquiera de estas personas. Excepto por el que mezcló barras y barras invertidas, podrían ser ellas si lo desean).
Puede obtener la unidad y la ruta + archivo de esta manera:
Obtenga la ruta y el archivo:
Obtener los nombres de las carpetas individuales no es especialmente conveniente, pero es el tipo de incomodidad honesta que aumenta el placer de encontrar algo que realmente funciona bien:
(Aparece un
"\"
al comienzofolders
si la ruta era originalmente absoluta. Podría perder un poco de código si no lo deseara).fuente
if path.endswith("/"):
ypath = path[:-1]
.yo lo haría
Primero normalice la cadena de ruta en una cadena adecuada para el sistema operativo. Entonces
os.sep
debe ser seguro de usar como delimitador en la división de la función de cadena.fuente
os.path.normpath(a_path).split(os.path.sep)
os.path.normpath(path).lstrip(os.path.sep).split(os.path.sep)
normpath
reconocerá la barra diagonal como un separador. En Linux,normpath
simplemente supondrá que tiene un directorio llamado\1\2
y un archivo o directorio llamado dentro3
.Simplemente puede usar el enfoque más pitónico (en mi humilde opinión):
Lo que te dará:
La clave aquí es usar en
os.sep
lugar de'\\'
o'/'
, ya que esto lo hace independiente del sistema.Para eliminar los dos puntos de la letra de la unidad (aunque no veo ninguna razón por la que quiera hacer eso), puede escribir:
fuente
some times
. Otras veces (al menos en Windows) encontrará rutas que se parecenfolder\folder2\folder3/file.txt
. Es mejor normalizar primero (os.path.normpath) el camino y luego dividirlo./foo//bar
). Vea la respuesta de Tompa para una solución más robusta.En Python> = 3.4 esto se ha vuelto mucho más simple. Ahora puede usar
pathlib.Path.parts
para obtener todas las partes de una ruta.Ejemplo:
En una instalación de Windows de Python 3, esto supondrá que está trabajando con rutas de Windows, y en * nix asumirá que está trabajando con rutas posix. Esto suele ser lo que desea, pero si no es así, puede usar las clases
pathlib.PurePosixPath
opathlib.PureWindowsPath
según sea necesario:Editar: También hay un backport para python 2 disponible: pathlib2
fuente
El problema aquí comienza con cómo estás creando la cadena en primer lugar.
Hecho de esta manera, Python está tratando de caso especial siguientes:
\s
,\m
,\f
, y\T
. En su caso,\f
se trata como un avance de página (0x0C) mientras que las demás barras invertidas se manejan correctamente. Lo que debe hacer es uno de estos:Luego, una vez que separe cualquiera de estos, obtendrá el resultado que desea.
fuente
split()
oreplace()
al trabajo por alguna razón - me hacía cada vez valores hex. Sin embargo, tienes razón, creo que estaba ladrando el árbol equivocado con la idea de cadena cruda; creo que solo estaba usandosplit()
incorrectamente. Porque probé algunas de estas solucionessplit()
y ahora funcionan para mí.Para una solución algo más concisa, considere lo siguiente:
fuente
/
. Además, le da una cadena vacía al comienzo de la lista si su ruta comienza con/
En realidad, no puedo aportar una respuesta real a esta (ya que vine aquí con la esperanza de encontrarla yo mismo), pero para mí la cantidad de enfoques diferentes y todas las advertencias mencionadas es el indicador más seguro de que el módulo os.path de Python necesita desesperadamente esto como una función incorporada.
fuente
La forma funcional, con un generador .
En acción:
fuente
Esto funciona para mi:
Claro que es posible que también necesite quitar el colon del primer componente, pero mantenerlo hace posible volver a ensamblar la ruta.
El
r
modificador marca el literal de cadena como "sin procesar"; observe cómo las barras invertidas incrustadas no se duplican.fuente
r
frente de tu cadena, ¿a qué se refiere eso?\
caracteres. Es útil para usar siempre que estés haciendo rutas.os.path.split
yos.pathsep
, considerando que ambos son mucho más portátiles de lo que ha escrito. Puede que no le importe a OP ahora, pero lo hará cuando esté escribiendo algo que necesite mover plataformas.Las cosas acerca de sobre
mypath.split("\\")
se expresarían mejor comomypath.split(os.sep)
.sep
es el separador de ruta para su plataforma particular (por ejemplo,\
para Windows,/
para Unix, etc.), y la compilación de Python sabe cuál usar. Si lo usasep
, entonces su código será independiente de la plataforma.fuente
os.path.split
. Desea tener cuidadoos.pathsep
, porque está:
en mi versión de Python en OS X (yos.path.split
se maneja correctamente/
).os.sep
noos.pathsep
. Siga la sabiduría de losos.sep
documentos: tenga en cuenta que saber esto no es suficiente para poder analizar o concatenar nombres de ruta: use os.path.split () y os.path.join ().re.split () puede ayudar un poco más que string.split ()
Si también desea admitir rutas de Linux y Mac, simplemente agregue el filtro (Ninguno, resultado), para que elimine el '' no deseado de la división () ya que sus rutas comienzan con '/' o '//'. por ejemplo '// mount / ...' o '/ var / tmp /'
fuente
Puedes recursivamente
os.path.split
la cadenaProbar esto contra algunas cadenas de ruta y volver a montar la ruta con
os.path.join
Es posible que el primer elemento de la lista deba tratarse de manera diferente según cómo desee tratar las letras de unidad, las rutas UNC y las rutas absolutas y relativas. Cambiar el último
[p]
a[os.path.splitdrive(p)]
fuerza el problema dividiendo la letra de unidad y la raíz del directorio en una tupla.Editar: me he dado cuenta de que esta respuesta es muy similar a la dada anteriormente por el usuario1556435 . Dejo mi respuesta, ya que el manejo del componente de unidad de la ruta es diferente.
fuente
Al igual que otros explicaron: su problema surgió del uso
\
, que es el carácter de escape en cadena literal / constante. OTOH, si tuviera esa cadena de ruta de archivo de otra fuente (leída desde un archivo, consola o devuelta por la función os), no habría habido problemas para dividirse en '\\' o r '\'.Y al igual que otros sugirieron, si desea usar
\
en el literal del programa, debe duplicarlo\\
o todo el literal debe tener el prefijor
, asír'lite\ral'
or"lite\ral"
para evitar que el analizador convierta eso\
y el carácterr
CR (retorno de carro).Sin embargo, hay una forma más: ¡simplemente no use
\
nombres de ruta de barra invertida en su código! Desde el siglo pasado, Windows reconoce y funciona bien con nombres de ruta que usan barra diagonal como separador de directorios/
. De alguna manera, no mucha gente lo sabe ... pero funciona:Por cierto, esto hará que su código funcione en Unix, Windows y Mac ... porque todos ellos se usan
/
como separador de directorios ... incluso si no desea usar las constantes predefinidas del móduloos
.fuente
var = var.replace('\\','/')
- reemplace \ con / y continúe trabajando solo con barras diagonales :)Supongamos que tiene un archivo
filedata.txt
con contenido:Puede leer y dividir las rutas de archivo:
fuente
Uso lo siguiente, ya que usa la función os.path.basename, no agrega barras a la lista devuelta. También funciona con barras inclinadas de cualquier plataforma: es decir, windows \ \ o unix's /. Y además, no agrega el \\\\ que Windows usa para las rutas del servidor :)
Entonces, para '\\\\ server \\ folder1 \\ folder2 \\ folder3 \\ folder4'
usted obtiene
['servidor', 'carpeta1', 'carpeta2', 'carpeta3', 'carpeta4']
fuente
os.path.join()
debería devolver la cadena original. Yo diría que la salida correcta para su entrada de ejemplo es[r'\\','server','folder1','folder2','folder3','folder4']
. Es decir, quéos.path.split()
hace.No estoy seguro de si esto responde completamente a la pregunta, pero me divertí mucho escribiendo esta pequeña función que mantiene una pila, se adhiere a las manipulaciones basadas en os.path y devuelve la lista / pila de elementos.
fuente
Debajo de la línea de código puede manejar:
ruta = re.split (r '[/// \]', ruta)
fuente
Uno recursivo para la diversión.
No es la respuesta más elegante, pero debería funcionar en todas partes:
fuente
utilizar
ntpath.split()
fuente
d:\\stuff
,morestuff\x0curtherdown\thefile.mux
)d:\\stuff, morestuff\x0curtherdown\thefile.mux
'\x0c'
es el carácter del feed del formulario. La forma de crear el carácter de fuente de formulario es '\ f'. Si realmente desea la cadena literal '\ f', tiene dos opciones:'\\f'
or'\f'
.