Eu tenho uma variável de seqüência de caracteres que representa um caminho dos, por exemplo:
var = "d:\stuff\morestuff\furtherdown\THEFILE.txt"
Eu quero dividir esta string em:
[ "d", "stuff", "morestuff", "furtherdown", "THEFILE.txt" ]
Eu tentei usar split()
e, replace()
mas eles apenas processam a primeira barra invertida ou inserem números hexadecimais na string.
Eu preciso converter essa variável de string em uma string bruta de alguma forma, para que eu possa analisá-la.
Qual é a melhor forma de fazer isso?
Devo acrescentar também que o conteúdo do var
caminho que estou tentando analisar é realmente o valor de retorno de uma consulta de linha de comando. Não são os dados do caminho que eu me gero. Ele é armazenado em um arquivo e a ferramenta de linha de comando não vai escapar das barras invertidas.
os.path.split
não está funcionando para você, porque você não está escapando dessa string corretamente.r"d:\stuff\morestuff\furtherdown\THEFILE.txt"
para impedir que coisas como\s
sejam mal interpretadas.Respostas:
Já fui mordido várias vezes por pessoas que escreviam suas próprias funções de mexer no caminho e erravam. Espaços, barras, barras invertidas, dois pontos - as possibilidades de confusão não são infinitas, mas os erros são facilmente cometidos de qualquer maneira. Portanto, sou um defensor do uso
os.path
e recomendo-o nessa base.(No entanto, o caminho para a virtude não é o mais fácil de seguir, e muitas pessoas, ao descobrirem isso, são tentadas a seguir um caminho escorregadio direto para a condenação. Elas não perceberão até que um dia tudo desmoronar, e elas - ou , mais provavelmente, outra pessoa - precisa descobrir por que tudo deu errado, e alguém criou um nome de arquivo que mistura barras e barras invertidas - e algumas pessoas sugerem que a resposta é "não fazer isso". Com exceção de quem misturou barras e barras invertidas - você pode ser elas, se quiser.)
Você pode obter a unidade e o caminho + arquivo assim:
Obtenha o caminho e o arquivo:
Obter nomes de pastas individuais não é especialmente conveniente, mas é o tipo de desconforto mediano honesto que aumenta o prazer de encontrar algo que realmente funciona bem mais tarde:
(Isso aparece
"\"
no início defolders
se o caminho era originalmente absoluto. Você pode perder um pouco de código se não quiser.)fonte
if path.endswith("/"):
epath = path[:-1]
.eu faria
Primeiro normalize a sequência do caminho em uma sequência adequada para o sistema operacional. Em seguida,
os.sep
deve ser seguro usá-lo como um delimitador na divisão da função de sequência.fonte
os.path.normpath(a_path).split(os.path.sep)
os.path.normpath(path).lstrip(os.path.sep).split(os.path.sep)
normpath
reconhecerá a barra como um separador. No Linux,normpath
basta assumir que você tem um diretório chamado\1\2
e um arquivo ou diretório dentro dele chamado3
.Você pode simplesmente usar a abordagem mais Pythonic (IMHO):
O que lhe dará:
A dica aqui é usar em
os.sep
vez de'\\'
ou'/'
, pois isso o torna independente do sistema.Para remover dois pontos da letra da unidade (embora eu não veja nenhuma razão para fazer isso), você pode escrever:
fonte
some times
. Outras vezes (no Windows, pelo menos), você encontrará caminhos parecidosfolder\folder2\folder3/file.txt
. É melhor normalizar primeiro (os.path.normpath) o caminho e depois dividi-lo./foo//bar
). Veja a resposta da Tompa para uma solução mais robusta.No Python> = 3.4, isso se tornou muito mais simples. Agora você pode usar
pathlib.Path.parts
para obter todas as partes de um caminho.Exemplo:
Em uma instalação do Python 3 no Windows, isso pressupõe que você esteja trabalhando com caminhos do Windows e, no * nix, assumirá que você está trabalhando com caminhos do posix. Isso geralmente é o que você deseja, mas se não for, pode usar as classes
pathlib.PurePosixPath
oupathlib.PureWindowsPath
conforme necessário:Edit: Há também um backport para python 2 disponível: pathlib2
fonte
O problema aqui começa com como você está criando a string em primeiro lugar.
Feito desta forma, Python está tentando caso especial estes:
\s
,\m
,\f
, e\T
. No seu caso,\f
está sendo tratado como um avanço de página (0x0C) enquanto as outras barras invertidas são tratadas corretamente. O que você precisa fazer é um destes:Depois de dividir um desses, você obterá o resultado desejado.
fonte
split()
oureplace()
trabalhei por algum motivo - continuei recebendo valores hexadecimais. Você está certo, porém, acho que estava latindo na árvore errada com a ideia de cadeia bruta - acho que estava usandosplit()
incorretamente. Porque eu tentei algumas dessas soluções usandosplit()
e elas funcionam para mim agora.Para uma solução um pouco mais concisa, considere o seguinte:
fonte
/
. Além disso, fornece uma string vazia no início da lista, se o caminho começar com #/
Na verdade, não posso contribuir com uma resposta real para essa (como eu vim aqui esperando encontrar uma), mas para mim o número de abordagens diferentes e todas as advertências mencionadas é o indicador mais seguro de que o módulo os.path do Python precisa desesperadamente disso. como uma função interna.
fonte
A maneira funcional, com um gerador .
Em ação:
fonte
Funciona para mim:
Claro, talvez você precise remover o cólon do primeiro componente, mas mantê-lo possibilita a remontagem do caminho.
O
r
modificador marca a string literal como "bruta"; observe como as barras invertidas incorporadas não são duplicadas.fonte
r
na frente da sua string, a que isso se refere?\
caracteres. É útil usar sempre que você estiver fazendo caminhos.os.path.split
eos.pathsep
, considerando que ambos são muito mais portáteis do que o que você escreveu. Pode não ser importante para o OP agora, mas será quando ele estiver escrevendo algo que precisa mover plataformas.O material sobre about
mypath.split("\\")
seria melhor expresso comomypath.split(os.sep)
.sep
é o separador de caminho para sua plataforma específica (por exemplo,\
para Windows,/
Unix etc.), e a compilação Python sabe qual usar. Se você usarsep
, seu código será independente de plataforma.fonte
os.path.split
. Você quer ter cuidadoos.pathsep
, porque está:
na minha versão do Python no OS X (eos.path.split
lida corretamente/
).os.sep
nãoos.pathsep
. Siga a sabedoria dosos.sep
documentos: Observe que saber isso não é suficiente para poder analisar ou concatenar nomes de caminho - use os.path.split () e os.path.join ().re.split () pode ajudar um pouco mais do que string.split ()
Se você também deseja oferecer suporte a caminhos Linux e Mac, basta adicionar filtro (Nenhum, resultado), para remover os '' indesejados da divisão (), pois os caminhos começam com '/' ou '//'. por exemplo '// mount / ...' ou '/ var / tmp /'
fonte
Você pode recursivamente
os.path.split
a stringTestando isso em algumas cadeias de caminho e remontando o caminho com
os.path.join
O primeiro elemento da lista pode precisar ser tratado de maneira diferente, dependendo de como você deseja lidar com letras de unidade, caminhos UNC e caminhos absolutos e relativos. Alterar o último
[p]
para[os.path.splitdrive(p)]
força o problema dividindo a letra da unidade e o diretório raiz em uma tupla.Edit: Eu percebi que esta resposta é muito semelhante à dada acima pelo user1556435 . Estou deixando minha resposta, pois a manipulação do componente da unidade do caminho é diferente.
fonte
Assim como outros explicaram - o problema foi causado pelo uso
\
, que é um caractere de escape na string literal / constante. OTOH, se você tivesse a sequência do caminho do arquivo de outra fonte (lida do arquivo, console ou retornada pela função os) - não haveria problemas de divisão em '\\' ou r '\'.E, assim como outros sugeriram, se você quiser usar
\
no literal programa, você tem que quer duplicá-lo\\
ou todo o literal tem de ser precedido porr
, como assimr'lite\ral'
our"lite\ral"
para evitar o analisador converter esse\
er
para CR caracteres (retorno de carro).Porém, há mais uma maneira - apenas não use
\
nomes de caminho de barra invertida no seu código! Desde o século passado, o Windows reconhece e funciona bem com nomes de caminho que usam barra como separador de diretório/
! De alguma forma, muitas pessoas não sabem disso .. mas funciona:A propósito, isso fará com que seu código funcione no Unix, Windows e Mac ... porque todos eles usam
/
como separador de diretório ... mesmo que você não queira usar as constantes predefinidas do móduloos
.fonte
var = var.replace('\\','/')
- substitua \ por / e continue trabalhando apenas com barras :) :)Vamos supor que você tenha um arquivo
filedata.txt
com conteúdo:Você pode ler e dividir os caminhos do arquivo:
fonte
Eu uso o seguinte, pois, como ele usa a função os.path.basename, ele não adiciona nenhuma barra à lista retornada. Também funciona com as barras de qualquer plataforma: por exemplo, \\ da janela ou / do unix. Além disso, ele não adiciona o \\\\ que o Windows usa para os caminhos do servidor :)
Portanto, para '\\\\ server \\ folder1 \\ folder2 \\ folder3 \\ folder4'
você recebe
['servidor', 'pasta1', 'pasta2', 'pasta3', 'pasta4']
fonte
os.path.join()
deve retornar a string original. Eu diria que a saída correta para o seu exemplo de entrada é[r'\\','server','folder1','folder2','folder3','folder4']
. Ou seja, o queos.path.split()
faz.Na verdade, não tenho certeza se isso responde totalmente à pergunta, mas me diverti escrevendo essa pequena função que mantém uma pilha, adere às manipulações baseadas no os.path e retorna a lista / pilha de itens.
fonte
A linha de código abaixo pode lidar com:
caminho = re.split (r '[/// \]', caminho)
fonte
Um recursivo para a diversão.
Não é a resposta mais elegante, mas deve funcionar em qualquer lugar:
fonte
usar
ntpath.split()
fonte
d:\\stuff
,morestuff\x0curtherdown\thefile.mux
)d:\\stuff, morestuff\x0curtherdown\thefile.mux
'\x0c'
é o caractere de feed de formulário. A maneira de criar o caractere de feed de formulário é '\ f'. Se você realmente deseja a string literal '\ f', você tem duas opções:'\\f'
our'\f'
.