Mam zmienną typu string, która reprezentuje ścieżkę dos np:
var = "d:\stuff\morestuff\furtherdown\THEFILE.txt"
Chcę podzielić ten ciąg na:
[ "d", "stuff", "morestuff", "furtherdown", "THEFILE.txt" ]
Próbowałem użyć split()
i replace()
ale albo przetwarzają tylko pierwszy lewy ukośnik, albo wstawiają liczby szesnastkowe do ciągu.
Muszę jakoś przekonwertować tę zmienną łańcuchową na nieprzetworzony ciąg, aby móc ją przeanalizować.
Jak najlepiej to zrobić?
Powinienem również dodać, że zawartość var
np. Ścieżki, którą próbuję przeanalizować, jest w rzeczywistości wartością zwracaną przez zapytanie w wierszu poleceń. To nie dane o ścieżkach, które sam generuję. Jest przechowywany w pliku, a narzędzie wiersza poleceń nie ucieknie przed ukośnikami odwrotnymi.
os.path.split
to nie działa, ponieważ nie unikasz poprawnie tego ciągu.r"d:\stuff\morestuff\furtherdown\THEFILE.txt"
aby uniknąć takich rzeczy, jak\s
błędna interpretacja.Odpowiedzi:
Wiele razy byłem gryziony przez ludzi piszących własną ścieżkę, bawiąc się funkcjami i robiąc to źle. Spacje, ukośniki, ukośniki odwrotne, dwukropki - możliwości pomyłki nie są nieskończone, ale i tak łatwo popełnić błędy. Więc jestem zwolennikiem stosowania
os.path
i polecam go na tej podstawie.(Jednak droga do cnoty nie należy do najłatwiejszych i wielu ludzi, gdy ją odkrywają, kusi, aby pójść śliską ścieżką prosto do potępienia. Nie zdadzą sobie sprawy, aż pewnego dnia wszystko się rozpadnie, a oni - lub bardziej prawdopodobne jest, że ktoś inny - musi dowiedzieć się, dlaczego wszystko poszło nie tak i okazuje się, że ktoś utworzył nazwę pliku zawierającą ukośniki i ukośniki odwrotne - a ktoś sugeruje, że odpowiedź brzmi „tego nie robić”. Don ' Nie bądź żadną z tych osób. Z wyjątkiem tego, który pomieszał ukośniki i ukośniki - możesz nimi być, jeśli chcesz).
Możesz uzyskać dysk i ścieżkę + plik w ten sposób:
Uzyskaj ścieżkę i plik:
Uzyskanie poszczególnych nazw folderów nie jest szczególnie wygodne, ale jest to rodzaj uczciwego dyskomfortu, który zwiększa przyjemność późniejszego znalezienia czegoś, co faktycznie działa dobrze:
(Ten Zdejmuje
"\"
na początkufolders
, jeśli ścieżka była początkowo absolutna. Można stracić kawałek kodu, jeśli nie chcemy.)źródło
if path.endswith("/"):
ipath = path[:-1]
.chciałbym zrobić
Najpierw znormalizuj ciąg ścieżki do odpowiedniego ciągu dla systemu operacyjnego. Następnie
os.sep
musi być bezpieczny do użycia jako separatora w funkcji split.źródło
os.path.normpath(a_path).split(os.path.sep)
os.path.normpath(path).lstrip(os.path.sep).split(os.path.sep)
normpath
rozpoznaje ukośnik jako separator. W systemie Linuxnormpath
po prostu przyjmiemy, że masz katalog o nazwie,\1\2
a wewnątrz niego plik lub katalog o nazwie3
.Możesz po prostu użyć najbardziej Pythonowego podejścia (IMHO):
Co da ci:
Wskazówka polega na tym, aby użyć
os.sep
zamiast'\\'
lub'/'
, ponieważ to czyni go niezależnym od systemu.Aby usunąć dwukropek z litery dysku (chociaż nie widzę żadnego powodu, dla którego chciałbyś to zrobić), możesz napisać:
źródło
some times
. Innym razem (przynajmniej w oknach) znajdziesz ścieżki, które wyglądają jakfolder\folder2\folder3/file.txt
. Lepiej jest najpierw znormalizować (os.path.normpath) ścieżkę, a następnie ją podzielić./foo//bar
.). Zobacz Tompa jest odpowiedź na bardziej solidne rozwiązanie.W Pythonie> = 3.4 stało się to znacznie prostsze. Możesz teraz użyć,
pathlib.Path.parts
aby uzyskać wszystkie części ścieżki.Przykład:
W przypadku instalacji Pythona 3 w systemie Windows zakłada się, że pracujesz ze ścieżkami systemu Windows, a na * nix zakłada, że pracujesz ze ścieżkami posix. Zwykle tego chcesz, ale jeśli tak nie jest, możesz użyć klas
pathlib.PurePosixPath
lubpathlib.PureWindowsPath
w razie potrzeby:Edycja: Dostępna jest również backport do Pythona 2: pathlib2
źródło
Problem tutaj zaczyna się od tego, jak tworzysz ciąg w pierwszej kolejności.
Sporządzono w ten sposób, Python próbuje szczególnym przypadku to:
\s
,\m
,\f
, i\T
. W twoim przypadku\f
jest traktowany jako wysuw formularza (0x0C), podczas gdy inne ukośniki odwrotne są obsługiwane poprawnie. Musisz wykonać jedną z następujących czynności:Następnie po podzieleniu jednego z nich uzyskasz pożądany wynik.
źródło
split()
lubreplace()
pracować - ciągle otrzymywałem wartości szesnastkowe. Masz jednak rację, myślę, że szczekałem na niewłaściwe drzewo z pomysłem na surowe struny - myślę, że po prostu użyłemsplit()
niewłaściwie. Ponieważ wypróbowałem niektóre z tych rozwiązań przy użyciusplit()
i teraz działają dla mnie.Aby uzyskać nieco bardziej zwięzłe rozwiązanie, rozważ następujące kwestie:
źródło
/
. Ponadto daje ci pusty ciąg na początku listy, jeśli twoja ścieżka zaczyna się od/
Właściwie nie mogę wnieść prawdziwej odpowiedzi na to pytanie (ponieważ przyszedłem tutaj, mając nadzieję, że sam go znajdę), ale dla mnie liczba różnych podejść i wszystkie wspomniane zastrzeżenia są najpewniejszym wskaźnikiem, że moduł os.path w Pythonie desperacko tego potrzebuje jako funkcja wbudowana.
źródło
Sposób funkcjonalny, z generatorem .
W akcji:
źródło
Mi to pasuje:
Oczywiście może być konieczne usunięcie okrężnicy z pierwszego składnika, ale zachowanie go umożliwia ponowne złożenie ścieżki.
W
r
modyfikujące znaki ciągiem znaków jako „surowe”; zwróć uwagę, że osadzone odwrotne ukośniki nie są podwajane.źródło
r
przed ciągiem znaków, do czego to się odnosi?\
znaki. Jest to przydatne, gdy tworzysz ścieżki.os.path.split
ios.pathsep
biorąc pod uwagę, że oba są o wiele bardziej przenośne niż to, co napisałeś. To może nie mieć teraz znaczenia dla OP, ale będzie, gdy pisze coś, co musi poruszyć platformy.To, co dotyczy,
mypath.split("\\")
byłoby lepiej wyrażone jakomypath.split(os.sep)
.sep
jest separatorem ścieżek dla twojej konkretnej platformy (np.\
dla Windows,/
dla Uniksa itp.), a kompilacja Pythona wie, której użyć. Jeśli używaszsep
, Twój kod będzie niezależny od platformy.źródło
os.path.split
. Chcesz być ostrożnyos.pathsep
, ponieważ jest:
na mojej wersji Pythona w OS X (ios.path.split
poprawnie obsługuje/
).os.sep
, że nieos.pathsep
. Postępuj zgodnie z mądrością zawartą wos.sep
dokumentacji: Zauważ, że znajomość tego nie jest wystarczająca do analizowania lub łączenia nazw ścieżek - użyj os.path.split () i os.path.join ().re.split () może pomóc trochę bardziej niż string.split ()
Jeśli chcesz również obsługiwać ścieżki Linuksa i Maca, po prostu dodaj filtr (Brak, wynik), aby usunąć niechciany znak „” z metody split (), ponieważ ich ścieżki zaczynają się od „/” lub „//”. na przykład „// mount / ...” lub „/ var / tmp /”
źródło
Możesz rekurencyjnie
os.path.split
ciągTestowanie tego na niektórych ciągach ścieżki i ponowne składanie ścieżki za pomocą
os.path.join
Pierwszy element listy może wymagać odmiennego traktowania w zależności od tego, jak chcesz radzić sobie z literami dysków, ścieżkami UNC oraz ścieżkami bezwzględnymi i względnymi. Zmiana ostatniego
[p]
na[os.path.splitdrive(p)]
wymusza problem poprzez podzielenie litery dysku i katalogu głównego na krotkę.Edycja: zdałem sobie sprawę, że ta odpowiedź jest bardzo podobna do tej podanej powyżej przez użytkownika1556435 . Zostawiam swoją odpowiedź, ponieważ obsługa komponentu napędu ścieżki jest inna.
źródło
Tak jak inni wyjaśnili - twój problem wynikał z użycia
\
, który jest znakiem ucieczki w literale / stałej ciągu. OTOH, gdybyś miał ten ciąg ścieżki pliku z innego źródła (odczytany z pliku, konsoli lub zwrócony przez funkcję os) - nie byłoby problemu z podziałem na '\\' lub r '\'.I tak jak inni sugerowali, jeśli chcesz użyć
\
w dosłownym programie, musisz albo go zduplikować,\\
albo cały literał musi być poprzedzony prefiksemr
, tak jak to,r'lite\ral'
lubr"lite\ral"
aby uniknąć konwersji przez parser tego\
ir
na znak CR (powrót karetki).Jest jeszcze jeden sposób - po prostu nie używaj nazw
\
ścieżek z odwrotnym ukośnikiem w swoim kodzie! Od zeszłego wieku Windows rozpoznaje i działa dobrze z nazwami ścieżek, które używają ukośnika jako separatora katalogu/
! Jakoś niewiele osób o tym wie ... ale to działa:To przy okazji sprawi, że twój kod będzie działał na Unix, Windows i Mac ... ponieważ wszystkie z nich używają
/
jako separatora katalogów ... nawet jeśli nie chcesz używać predefiniowanych stałych modułuos
.źródło
var = var.replace('\\','/')
- zamień \ na / i kontynuuj pracę tylko z ukośnikami w przód :)Załóżmy, że masz plik
filedata.txt
z zawartością:Możesz czytać i dzielić ścieżki plików:
źródło
Używam następującego, ponieważ ponieważ używa funkcji os.path.basename, nie dodaje żadnych ukośników do zwracanej listy. Działa również z ukośnikami dowolnej platformy: tj. \\ lub unixem /. Co więcej, nie dodaje \\\\, którego system Windows używa do ścieżek serwera :)
Tak więc dla „\\\\ serwer \\ folder1 \\ folder2 \\ folder3 \\ folder4”
dostajesz
[„serwer”, „folder1”, „folder2”, „folder3”, „folder4”]
źródło
os.path.join()
powinno zwrócić oryginalny ciąg. Powiedziałbym, że prawidłowe wyjście dla twojego przykładowego wejścia to[r'\\','server','folder1','folder2','folder3','folder4']
. Toos.path.split()
znaczy co robi.Właściwie nie jestem pewien, czy to w pełni odpowiada na pytanie, ale dobrze się bawiłem pisząc tę małą funkcję, która przechowuje stos, trzyma się manipulacji opartych na os.path i zwraca listę / stos elementów.
źródło
Poniższy wiersz kodu może obsłużyć:
path = re.split (r '[/// \]', ścieżka)
źródło
Jedna rekurencyjna dla zabawy.
Nie jest to najbardziej elegancka odpowiedź, ale powinna działać wszędzie:
źródło
posługiwać się
ntpath.split()
źródło
d:\\stuff
,morestuff\x0curtherdown\thefile.mux
)d:\\stuff, morestuff\x0curtherdown\thefile.mux
'\x0c'
to znak wysuwu formularza. Sposób tworzenia znaku wysuwu formularza to „\ f”. Jeśli naprawdę potrzebujesz literału „\ f”, masz dwie opcje:'\\f'
lubr'\f'
.