Ekstrak ekstensi dari nama file dengan Python


Jawaban:


1990

Iya. Gunakan os.path.splitext(lihat dokumentasi Python 2.X atau dokumentasi Python 3.X ):

>>> import os
>>> filename, file_extension = os.path.splitext('/path/to/somefile.ext')
>>> filename
'/path/to/somefile'
>>> file_extension
'.ext'

Tidak seperti kebanyakan upaya pemisahan string manual, os.path.splitextakan memperlakukan dengan benar /a/b.c/dsebagai tidak memiliki ekstensi alih-alih memiliki ekstensi .c/d, dan itu akan diperlakukan .bashrcsebagai tidak memiliki ekstensi alih-alih memiliki ekstensi .bashrc:

>>> os.path.splitext('/a/b.c/d')
('/a/b.c/d', '')
>>> os.path.splitext('.bashrc')
('.bashrc', '')

15
penggunaan basenamesedikit membingungkan di sini karena os.path.basename("/path/to/somefile.ext")akan kembali"somefile.ext"
Jiaaro

17
tidak akan endswith()tidak lebih portabel dan pythonic?
Sebastian Mach

79
@ klingt.net Nah, kalau begitu, .asdini benar-benar ekstensi !! Jika Anda memikirkannya, foo.tar.gzadalah file terkompresi gzip ( .gz) yang merupakan file tar ( .tar). Tapi itu adalah file gzip di tempat pertama. Saya tidak berharap untuk mengembalikan ekstensi ganda sama sekali.
nosklo

160
Konvensi penamaan fungsi Python standar benar-benar menjengkelkan - hampir setiap kali saya melihat kembali ini, saya salah mengartikannya splittext. Jika mereka hanya melakukan apa saja untuk menandakan jeda antara bagian dari nama ini, akan lebih mudah untuk mengenali bahwa itu adalah splitExtatau split_ext. Tentunya saya bukan satu-satunya orang yang melakukan kesalahan ini?
ArtOfWarfare

9
@Vingtoft Anda tidak menyebut-nyebut tentang FileStorage werkzeug dalam komentar Anda dan pertanyaan ini tidak ada hubungannya dengan skenario tertentu. Mungkin ada yang salah dengan cara Anda memasukkan nama file. os.path.splitext('somefile.ext')=> ('somefile', '.ext'). Jangan ragu memberikan contoh penghitung yang sebenarnya tanpa merujuk beberapa perpustakaan pihak ketiga.
Gewthen

400
import os.path
extension = os.path.splitext(filename)[1]

15
Karena penasaran, mengapa import os.pathbukan from os import path?
Kiswa

2
Oh, saya hanya ingin tahu apakah ada alasan khusus di baliknya (selain dari konvensi). Saya masih belajar Python dan ingin belajar lebih banyak!
Kiswa

55
itu benar-benar tergantung, jika Anda menggunakan from os import pathmaka nama pathdiambil di lingkup lokal Anda, juga orang lain yang melihat kode mungkin tidak segera tahu bahwa path adalah path dari modul os. Di mana seolah-olah Anda menggunakannya import os.pathmenyimpannya dalam osnamespace dan di mana pun Anda membuat panggilan, orang tahu itu path()dari osmodul segera.
dennmat

18
Saya tahu ini tidak berbeda secara semantik, tetapi saya pribadi menganggap konstruksinya _, extension = os.path.splitext(filename)jauh lebih bagus.
Tim Gilbert

3
Jika Anda ingin ekstensi sebagai bagian dari ekspresi yang lebih kompleks, [1] mungkin lebih berguna: if check_for_gzip and os.path.splitext(filename)[1] == '.gz':
gerardw

239

Baru dalam versi 3.4.

import pathlib

print(pathlib.Path('yourPath.example').suffix) # '.example'

Saya terkejut belum ada yang menyebutkan pathlib, pathlibLUAR BIASA!

Jika Anda membutuhkan semua sufiks (mis. Jika Anda memiliki .tar.gz), .suffixesakan mengembalikan daftar sufiks !


12
contoh untuk mendapatkan .tar.gz:''.join(pathlib.Path('somedir/file.tar.gz').suffixes)
user3780389

Jawaban yang bagus Saya menemukan tutorial ini lebih berguna daripada dokumentasi: zetcode.com/python/pathlib
user118967

@ user3780389 Bukankah "foo.bar.tar.gz" masih valid ".tar.gz"? Jika demikian, cuplikan Anda harus digunakan .suffixes[-2:]untuk memastikan hanya mendapatkan .tar.gz paling banyak.
jeromej

111
import os.path
extension = os.path.splitext(filename)[1][1:]

Untuk hanya mendapatkan teks ekstensi, tanpa titik.


73

Satu opsi mungkin terpisah dari titik:

>>> filename = "example.jpeg"
>>> filename.split(".")[-1]
'jpeg'

Tidak ada kesalahan saat file tidak memiliki ekstensi:

>>> "filename".split(".")[-1]
'filename'

Tetapi Anda harus berhati-hati:

>>> "png".split(".")[-1]
'png'    # But file doesn't have an extension

4
Ini akan menjadi kesal jika Anda mengunggah x.tar.gz
Kirill

19
Sebenarnya tidak. Perpanjangan file bernama "x.tar.gz" adalah "gz" bukan "tar.gz". os.path.splitext memberikan ".os" sebagai ekstensi juga.
Murat Çorlu

1
bisakah kita menggunakan [1] daripada [-1]. Saya tidak bisa mengerti [-1] dengan split
user765443

7
[-1] untuk mendapatkan item terakhir dari item yang dipisahkan oleh titik. Contoh:"my.file.name.js".split('.') => ['my','file','name','js]
Murat Çorlu

1
@BenjaminR ah ok, Anda membuat optimasi tentang daftar hasil. ['file', 'tar', 'gz']dengan 'file.tar.gz'.split('.') vs ['file.tar', 'gz'] dengan 'file.tar.gz'.rsplit('.', 1). ya, bisa jadi.
Murat Çorlu

40

layak ditambahkan yang lebih rendah di sana sehingga Anda tidak bertanya-tanya mengapa JPG tidak muncul dalam daftar Anda.

os.path.splitext(filename)[1][1:].strip().lower()

19

Salah satu solusi di atas berfungsi, tetapi di linux saya telah menemukan bahwa ada baris baru di akhir string ekstensi yang akan mencegah kecocokan dari berhasil. Tambahkan strip()metode sampai akhir. Sebagai contoh:

import os.path
extension = os.path.splitext(filename)[1][1:].strip() 

1
Untuk membantu pemahaman saya, bisakah Anda menjelaskan perilaku tambahan apa yang dijaga oleh indeks / slice kedua? (ie the [1:]in .splittext(filename)[1][1:]) - terima kasih sebelumnya
Samuel Harmer

1
Mencari tahu sendiri: splittext()(tidak seperti jika Anda memisahkan string menggunakan '.') Termasuk '.' karakter dalam ekstensi. Tambahan [1:]menghilangkannya.
Samuel Harmer

17

Dengan splitext ada masalah dengan file dengan ekstensi ganda (mis file.tar.gz. file.tar.bz2, Dll.)

>>> fileName, fileExtension = os.path.splitext('/path/to/somefile.tar.gz')
>>> fileExtension 
'.gz'

tetapi harus: .tar.gz

Solusi yang mungkin ada di sini


35
Tidak, seharusnya .gz
Robert Siemer

1
lakukan dua kali untuk mendapatkan 2 ekstensi?
maazza

1
@maazza ya. gunzip somefile.tar.gz apa nama file keluaran?
FlipMcF

1
Inilah sebabnya kami memiliki ekstensi 'tgz' yang artinya: tar + gzip! : D
Nuno Aniceto

1
@ Peterhil Saya tidak berpikir Anda ingin skrip python Anda untuk mengetahui aplikasi yang digunakan untuk membuat nama file. Itu sedikit keluar dari ruang lingkup pertanyaan. Jangan memilih pada contoh, 'filename.csv.gz' juga cukup valid.
FlipMcF

16

Anda dapat menemukan beberapa hal hebat dalam modul pathlib (tersedia dalam python 3.x).

import pathlib
x = pathlib.PurePosixPath("C:\\Path\\To\\File\\myfile.txt").suffix
print(x)

# Output 
'.txt'

14

Meskipun ini adalah topik lama, tetapi saya bertanya-tanya mengapa tidak ada yang menyebutkan api sangat sederhana dari python yang disebut rpartition dalam kasus ini:

untuk mendapatkan ekstensi path absolut file yang diberikan, Anda cukup mengetik:

filepath.rpartition('.')[-1]

contoh:

path = '/home/jersey/remote/data/test.csv'
print path.rpartition('.')[-1]

akan memberi Anda: 'csv'


1
Bagi yang belum terbiasa dengan API, rpartition mengembalikan tupel: ("string before the right-most occurrence of the separator", "the separator itself", "the rest of the string"). Jika tidak ada pemisah ditemukan, tupel kembali akan: ("", "", "the original string").
Nickolay

13

Hanya joinsemua pathlib suffixes.

>>> x = 'file/path/archive.tar.gz'
>>> y = 'file/path/text.txt'
>>> ''.join(pathlib.Path(x).suffixes)
'.tar.gz'
>>> ''.join(pathlib.Path(y).suffixes)
'.txt'

12

Terkejut ini belum disebutkan:

import os
fn = '/some/path/a.tar.gz'

basename = os.path.basename(fn)  # os independent
Out[] a.tar.gz

base = basename.split('.')[0]
Out[] a

ext = '.'.join(basename.split('.')[1:])   # <-- main part

# if you want a leading '.', and if no result `None`:
ext = '.' + ext if ext else None
Out[] .tar.gz

Manfaat:

  • Bekerja seperti yang diharapkan untuk apa pun yang dapat saya pikirkan
  • Tidak ada modul
  • Tidak ada regex
  • Lintas-platform
  • Mudah diperpanjang (mis. Tidak ada titik utama untuk ekstensi, hanya bagian terakhir dari ekstensi)

Sebagai fungsi:

def get_extension(filename):
    basename = os.path.basename(filename)  # os independent
    ext = '.'.join(basename.split('.')[1:])
    return '.' + ext if ext else None

1
Ini menghasilkan pengecualian ketika file tidak memiliki ekstensi apa pun.
thiruvenkadam

4
Jawaban ini benar-benar mengabaikan varian jika nama file mengandung banyak poin dalam nama. Contoh get_extension ('cmocka-1.1.0.tar.xz') => '.1.0.tar.xz' - salah.
PADYMKO

@ PADYMKO, IMHO kita tidak harus membuat nama file dengan berhenti penuh sebagai bagian dari nama file. Kode di atas tidak seharusnya menghasilkan 'tar.xz'
Douwe van der Leest

2
Ubah saja [-1]saat itu.
PascalVKooten

11

Anda dapat menggunakan splitpada filename:

f_extns = filename.split(".")
print ("The extension of the file is : " + repr(f_extns[-1]))

Ini tidak memerlukan perpustakaan tambahan


10
filename='ext.tar.gz'
extension = filename[filename.rfind('.'):]

2
Ini menghasilkan karakter terakhir filenameyang dikembalikan jika nama file tidak ada .sama sekali. Ini karena rfindpengembalian -1jika string tidak ditemukan.
mattst

6

Ini adalah teknik representasi string langsung: Saya melihat banyak solusi yang disebutkan, tetapi saya pikir sebagian besar melihat split. Namun Split melakukannya di setiap kemunculan "." . Apa yang Anda lebih suka cari adalah partisi.

string = "folder/to_path/filename.ext"
extension = string.rpartition(".")[-1]

2
rpartition sudah disarankan oleh @weiyixie .
Nickolay

5

Solusi lain dengan split kanan:

# to get extension only

s = 'test.ext'

if '.' in s: ext = s.rsplit('.', 1)[1]

# or, to get file name and extension

def split_filepath(s):
    """
    get filename and extension from filepath 
    filepath -> (filename, extension)
    """
    if not '.' in s: return (s, '')
    r = s.rsplit('.', 1)
    return (r[0], r[1])

5

Bahkan pertanyaan ini sudah dijawab Saya akan menambahkan solusinya di Regex.

>>> import re
>>> file_suffix = ".*(\..*)"
>>> result = re.search(file_suffix, "somefile.ext")
>>> result.group(1)
'.ext'

1
Atau \.[0-9a-z]+$seperti pada postingan ini .
pault

2

Satu-liner sejati, jika Anda suka regex. Dan tidak masalah bahkan jika Anda memiliki tambahan "." di tengah-tengah

import re

file_ext = re.search(r"\.([^.]+)$", filename).group(1)

Lihat di sini untuk hasilnya: Klik Di Sini


0

Ini adalah Metode Sederhana untuk mendapatkan Nama File & Ekstensi hanya dalam satu baris .

fName, ext = 'C:/folder name/Flower.jpeg'.split('/')[-1].split('.')

>>> print(fName)
Flower
>>> print(ext)
jpeg

Tidak seperti solusi lain, Anda tidak perlu mengimpor paket apa pun untuk ini.


2
ini tidak bekerja untuk semua file atau tipe misalnya 'archive.tar.gz
studioj

0

Untuk funsies ... kumpulkan saja ekstensi dalam dict, dan lacak semuanya dalam folder. Kemudian cukup tarik ekstensi yang Anda inginkan.

import os

search = {}

for f in os.listdir(os.getcwd()):
    fn, fe = os.path.splitext(f)
    try:
        search[fe].append(f)
    except:
        search[fe]=[f,]

extensions = ('.png','.jpg')
for ex in extensions:
    found = search.get(ex,'')
    if found:
        print(found)

Itu ide yang buruk. Kode Anda rusak untuk ekstensi file apa pun yang belum Anda tambahkan sebelumnya!
Robert

0

coba ini:

files = ['file.jpeg','file.tar.gz','file.png','file.foo.bar','file.etc']
pen_ext = ['foo', 'tar', 'bar', 'etc']

for file in files: #1
    if (file.split(".")[-2] in pen_ext): #2
        ext =  file.split(".")[-2]+"."+file.split(".")[-1]#3
    else:
        ext = file.split(".")[-1] #4
    print (ext) #5
  1. dapatkan semua nama file di dalam daftar
  2. memisahkan nama file dan memeriksa ekstensi kedua dari belakang, apakah ada dalam daftar pen_ext atau tidak?
  3. jika ya maka gabungkan dengan ekstensi terakhir dan atur sebagai ekstensi file
  4. jika tidak maka cukup letakkan ekstensi terakhir sebagai ekstensi file
  5. dan kemudian memeriksanya

1
Ini istirahat untuk banyak kasus khusus. Lihat jawaban yang diterima. Ini menciptakan kembali roda, hanya dengan cara kereta.
Robert

saya memperbarui jawaban saya
Ibnul Husainan

Halo! Sementara kode ini dapat menyelesaikan pertanyaan, termasuk penjelasan tentang bagaimana dan mengapa ini menyelesaikan masalah akan sangat membantu untuk meningkatkan kualitas posting Anda, dan mungkin menghasilkan lebih banyak suara. Ingatlah bahwa Anda menjawab pertanyaan untuk pembaca di masa depan, bukan hanya orang yang bertanya sekarang. Harap edit jawaban Anda untuk menambahkan penjelasan dan berikan indikasi tentang batasan dan asumsi apa yang berlaku.
Brian

@ Brian seperti itu?
Ibnul Husainan

Anda hanya memperburuknya, memecahkannya dengan cara baru. foo.taradalah nama file yang valid. Apa yang terjadi jika saya melemparkan itu pada kode Anda? Bagaimana dengan .bashrcatau foo? Ada fungsi perpustakaan untuk ini karena suatu alasan ...
Robert

-2
# try this, it works for anything, any length of extension
# e.g www.google.com/downloads/file1.gz.rs -> .gz.rs

import os.path

class LinkChecker:

    @staticmethod
    def get_link_extension(link: str)->str:
        if link is None or link == "":
            return ""
        else:
            paths = os.path.splitext(link)
            ext = paths[1]
            new_link = paths[0]
            if ext != "":
                return LinkChecker.get_link_extension(new_link) + ext
            else:
                return ""

-3
def NewFileName(fichier):
    cpt = 0
    fic , *ext =  fichier.split('.')
    ext = '.'.join(ext)
    while os.path.isfile(fichier):
        cpt += 1
        fichier = '{0}-({1}).{2}'.format(fic, cpt, ext)
    return fichier

-5
name_only=file_name[:filename.index(".")

Itu akan memberi Anda nama file hingga yang pertama ".", Yang akan menjadi yang paling umum.


1
pertama, dia tidak perlu nama, tetapi ekstensi. Kedua, bahkan jika ia membutuhkan nama, itu akan salah dengan file seperti:file.name.ext
ya_dimon

Seperti disebutkan oleh @ya_dimon, ini tidak akan berfungsi untuk nama file dengan titik. Plus, dia membutuhkan ekstensi!
Umar Dastgir
Dengan menggunakan situs kami, Anda mengakui telah membaca dan memahami Kebijakan Cookie dan Kebijakan Privasi kami.
Licensed under cc by-sa 3.0 with attribution required.