Saya memiliki variabel string yang mewakili path dos, misalnya:
var = "d:\stuff\morestuff\furtherdown\THEFILE.txt"
Saya ingin membagi string ini menjadi:
[ "d", "stuff", "morestuff", "furtherdown", "THEFILE.txt" ]
Saya telah mencoba menggunakan split()
dan replace()
tetapi mereka hanya memproses backslash pertama atau mereka memasukkan angka hex ke dalam string.
Saya perlu mengubah variabel string ini menjadi string mentah entah bagaimana sehingga saya dapat menguraikannya.
Apa cara terbaik untuk melakukan ini?
Saya juga harus menambahkan bahwa isi var
yaitu jalan yang saya coba uraikan, sebenarnya adalah nilai balik dari permintaan baris perintah. Bukan jalur data yang saya hasilkan sendiri. Ini disimpan dalam file, dan alat baris perintah tidak akan lepas dari garis miring terbalik.
os.path.split
itu tidak berfungsi untuk Anda karena Anda tidak melarikan diri dari string itu dengan benar.r"d:\stuff\morestuff\furtherdown\THEFILE.txt"
untuk mencegah hal-hal seperti\s
disalahtafsirkan.Jawaban:
Saya telah digigit banyak kali oleh orang-orang menulis fungsi mengutak-atik jalur mereka sendiri dan salah. Ruang, garis miring, garis miring terbalik, titik dua - kemungkinan kebingungan tidak terbatas, tetapi kesalahan tetap mudah dilakukan. Jadi saya ngotot untuk penggunaan
os.path
, dan merekomendasikannya atas dasar itu.(Namun, jalan menuju kebajikan bukanlah yang paling mudah diambil, dan banyak orang ketika menemukan ini tergoda untuk mengambil jalan yang licin langsung ke kutukan. Mereka tidak akan menyadari sampai suatu hari semuanya hancur berkeping-keping, dan mereka - atau , lebih mungkin, orang lain - harus mencari tahu mengapa semuanya salah, dan ternyata seseorang membuat nama file yang mencampuradukkan garis miring dan garis miring terbalik - dan beberapa orang menyarankan bahwa jawabannya adalah "tidak melakukan itu". "Jangan menjadi salah satu dari orang-orang ini. Kecuali untuk orang yang mencampuradukkan garis miring dan garis miring terbalik - Anda bisa menjadi mereka jika Anda mau.)
Anda bisa mendapatkan drive dan path + file seperti ini:
Dapatkan path dan file:
Mendapatkan nama-nama folder individual tidak terlalu nyaman, tetapi itu adalah jenis ketidaknyamanan lumayan menengah yang mempertinggi kesenangan kemudian menemukan sesuatu yang benar-benar berfungsi dengan baik:
(Ini muncul
"\"
di awalfolders
jika path awalnya absolut. Anda bisa kehilangan sedikit kode jika Anda tidak menginginkannya.)sumber
if path.endswith("/"):
danpath = path[:-1]
.Saya akan lakukan
Pertama menormalkan string path menjadi string yang tepat untuk OS. Maka
os.sep
harus aman untuk digunakan sebagai pembatas dalam fungsi string split.sumber
os.path.normpath(a_path).split(os.path.sep)
os.path.normpath(path).lstrip(os.path.sep).split(os.path.sep)
normpath
akan mengenali garis miring sebagai pemisah. Di Linux, Andanormpath
cukup berasumsi bahwa Anda memiliki direktori yang dipanggil\1\2
dan file atau direktori di dalamnya disebut3
.Anda cukup menggunakan pendekatan Pythonic (IMHO) yang paling:
Yang akan memberi Anda:
Petunjuk di sini adalah untuk menggunakan
os.sep
alih-alih'\\'
atau'/'
, karena ini membuatnya sistem independen.Untuk menghapus titik dua dari huruf drive (walaupun saya tidak melihat alasan mengapa Anda ingin melakukan itu), Anda dapat menulis:
sumber
some times
. Kali lain (setidaknya di windows) Anda akan menemukan jalan yang terlihat sepertifolder\folder2\folder3/file.txt
. Lebih baik untuk menormalkan dulu (os.path.normpath) jalan dan kemudian membaginya./foo//bar
). Lihat Tompa 's jawaban untuk solusi yang lebih kuat.Dalam Python> = 3,4 ini menjadi jauh lebih sederhana. Anda sekarang dapat menggunakan
pathlib.Path.parts
untuk mendapatkan semua bagian dari jalan.Contoh:
Pada instalasi Windows dari Python 3 ini akan menganggap bahwa Anda bekerja dengan jalur Windows, dan pada * nix itu akan menganggap bahwa Anda bekerja dengan jalur posix. Ini biasanya yang Anda inginkan, tetapi jika tidak, Anda bisa menggunakan kelas
pathlib.PurePosixPath
ataupathlib.PureWindowsPath
sesuai kebutuhan:Sunting: Ada juga backport ke python 2 yang tersedia: pathlib2
sumber
Masalahnya di sini dimulai dengan bagaimana Anda membuat string di tempat pertama.
Dilakukan dengan cara ini, Python sedang mencoba untuk kasus khusus ini:
\s
,\m
,\f
, dan\T
. Dalam kasus Anda,\f
sedang diperlakukan sebagai formfeed (0x0C) sementara backslash lainnya ditangani dengan benar. Yang perlu Anda lakukan adalah salah satunya:Kemudian setelah Anda membagi salah satu dari ini, Anda akan mendapatkan hasil yang Anda inginkan.
sumber
split()
ataureplace()
bekerja karena suatu alasan - saya terus mendapatkan nilai hex. Anda benar, saya pikir saya menggonggong pohon yang salah dengan ide string mentah - saya pikir saya hanya menggunakansplit()
salah. Karena saya mencoba beberapa solusi ini menggunakansplit()
dan mereka bekerja untuk saya sekarang.Untuk solusi yang lebih ringkas, pertimbangkan hal berikut:
sumber
/
. Juga, memberi Anda string kosong di awal daftar jika jalur Anda mulai dengan/
Saya tidak bisa benar-benar menyumbangkan jawaban nyata untuk yang ini (karena saya datang ke sini berharap untuk menemukan sendiri), tetapi bagi saya jumlah pendekatan yang berbeda dan semua peringatan yang disebutkan adalah indikator paling pasti bahwa modul os.path Python sangat membutuhkan ini sebagai fungsi bawaan.
sumber
Cara fungsional, dengan generator .
Beraksi:
sumber
Ini bekerja untuk saya:
Tentu Anda mungkin perlu juga menghapus usus besar dari komponen pertama, tetapi menjaganya agar tetap memungkinkan untuk merakit kembali jalan.
The
r
tanda pengubah string literal sebagai "mentah"; perhatikan bagaimana backslash tertanam tidak digandakan.sumber
r
depan string Anda, apa maksudnya?\
karakter. Ini berguna untuk digunakan setiap kali Anda melakukan jalur.os.path.split
danos.pathsep
, mengingat keduanya jauh lebih portabel daripada yang Anda tulis. Mungkin tidak masalah untuk OP sekarang, tetapi ketika dia menulis sesuatu yang perlu memindahkan platform.Hal-hal tentang
mypath.split("\\")
akan lebih baik dinyatakan sebagaimypath.split(os.sep)
.sep
adalah pemisah jalur untuk platform khusus Anda (misalnya,\
untuk Windows,/
untuk Unix, dll.), dan bangunan Python tahu mana yang akan digunakan. Jika Anda menggunakansep
, maka kode Anda akan menjadi platform agnostik.sumber
os.path.split
. Anda ingin berhati-hati denganos.pathsep
, karena itu:
pada versi saya Python di OS X (danos.path.split
menangani dengan benar/
).os.sep
bukanos.pathsep
. Ikuti kebijaksanaan dalamos.sep
dokumen: Perhatikan bahwa mengetahui ini tidak cukup untuk dapat menguraikan atau menggabungkan nama path - gunakan os.path.split () dan os.path.join ().re.split () dapat membantu sedikit lebih banyak daripada string.split ()
Jika Anda juga ingin mendukung jalur Linux dan Mac, cukup tambahkan filter (Tidak ada, hasil), sehingga akan menghapus '' yang tidak diinginkan dari split () karena jalurnya dimulai dengan '/' atau '//'. misalnya '// mount / ...' atau '/ var / tmp /'
sumber
Anda dapat secara rekursif
os.path.split
stringMenguji ini terhadap beberapa string path, dan memasang kembali path dengan
os.path.join
Elemen pertama dari daftar mungkin perlu diperlakukan berbeda tergantung pada bagaimana Anda ingin berurusan dengan huruf drive, jalur UNC dan jalur absolut dan relatif. Mengubah yang terakhir
[p]
untuk[os.path.splitdrive(p)]
memaksa masalah dengan memecah huruf drive dan direktori root menjadi tuple.Sunting: Saya menyadari bahwa jawaban ini sangat mirip dengan yang diberikan di atas oleh user1556435 . Saya meninggalkan jawaban saya karena penanganan komponen drive jalur berbeda.
sumber
Seperti yang dijelaskan orang lain - masalah Anda berasal dari penggunaan
\
, yaitu karakter pelarian dalam string literal / konstan. OTOH, jika Anda memiliki string path file dari sumber lain (baca dari file, konsol atau dikembalikan dengan fungsi os) - tidak akan ada masalah pemisahan pada '\\' atau r '\'.Dan seperti yang disarankan orang lain, jika Anda ingin menggunakannya
\
dalam program literal, Anda harus menduplikasinya\\
atau seluruh literal harus diawali denganr
, seperti demikianr'lite\ral'
ataur"lite\ral"
untuk menghindari parser mengonversi itu\
danr
ke karakter CR (carriage return).Ada satu cara lagi - jangan gunakan backslash
\
pathnames dalam kode Anda! Sejak abad terakhir Windows mengenali dan bekerja dengan baik dengan nama path yang menggunakan forward slash sebagai pemisah direktori/
! Entah bagaimana tidak banyak orang tahu itu .. tetapi ia bekerja:Ngomong-ngomong, kode Anda berfungsi di Unix, Windows, dan Mac ... karena semuanya digunakan
/
sebagai pemisah direktori ... bahkan jika Anda tidak ingin menggunakan konstanta yang sudah ditentukan sebelumnya dari modulos
.sumber
var = var.replace('\\','/')
- ganti \ dengan / dan lanjutkan bekerja dengan hanya memangkas :)Anggap Anda memiliki file
filedata.txt
dengan konten:Anda dapat membaca dan membagi jalur file:
sumber
Saya menggunakan berikut ini karena menggunakan fungsi os.path.basename itu tidak menambahkan garis miring ke daftar yang dikembalikan. Ini juga berfungsi dengan garis miring platform apa pun: yaitu jendela \ atau \ /. Dan lebih jauh lagi, ini tidak menambahkan Windows yang digunakan untuk jalur server :)
Jadi untuk '\\ server \\ folder1 \\ folder2 \\ folder3 \\ folder4'
Anda mendapatkan
['server', 'folder1', 'folder2', 'folder3', 'folder4']
sumber
os.path.join()
harus mengembalikan string asli. Saya akan mengatakan output yang benar untuk input contoh Anda adalah[r'\\','server','folder1','folder2','folder3','folder4']
. Yaitu apaos.path.split()
.Saya tidak benar-benar yakin apakah ini sepenuhnya menjawab pertanyaan, tetapi saya bersenang-senang menulis fungsi kecil ini yang menyimpan setumpuk, menempel pada manipulasi berbasis os.path, dan mengembalikan daftar / tumpukan item.
sumber
Baris kode di bawah ini dapat menangani:
path = re.split (r '[/// \]', path)
sumber
Satu rekursif untuk bersenang-senang.
Bukan jawaban yang paling elegan, tetapi harus bekerja di mana saja:
sumber
menggunakan
ntpath.split()
sumber
d:\\stuff
,morestuff\x0curtherdown\thefile.mux
)d:\\stuff, morestuff\x0curtherdown\thefile.mux
'\x0c'
adalah karakter umpan formulir. Cara membuat karakter umpan formulir adalah '\ f'. Jika Anda benar-benar menginginkan string literal '\ f', Anda memiliki dua opsi:'\\f'
ataur'\f'
.