Extragerea extensiei din numele fișierului în Python (Programare, Python, Nume De Fișiere, Extensie De Fișier)

Alex a intrebat.

Există o funcție pentru a extrage extensia dintr-un nume de fișier?

25 răspunsuri
nosklo

Da. Utilizați os.path.splitext(vezi Documentația Python 2.X sau documentația Python 3.X):

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

Spre deosebire de majoritatea încercărilor manuale de divizare a șirurilor de caractere, os.path.splitext va trata corect /a/b.c/d ca neavând nicio extensie în loc să aibă extensia .c/d, și va trata .bashrc ca neavând extensie în loc să aibă extensie .bashrc:

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

Comentarii

    17

  • utilizarea de basename este puțin confuză aici, deoarece os.path.basename("/path/to/somefile.ext") ar returna "somefile.ext" –  > Por Jiaaro.
  • 18

  • nu ar face-o endswith() nu ar fi mai portabil și mai pitoresc? –  > Por Sebastian Mach.
  • 81

  • @klingt.net Ei bine, în acest caz, .asd este într-adevăr extensia!!! Dacă te gândești la asta, foo.tar.gz este un fișier comprimat prin gzip (.gz) care se întâmplă să fie un fișier tar (.tar). Dar este un fișier fișier gzip în primul rând. Nu m-aș aștepta să returneze deloc extensia dublă. –  > Por nosklo.
  • 185

  • Convenția standard de denumire a funcțiilor Python este foarte enervantă – aproape de fiecare dată când mă uit din nou la această funcție, o confund ca fiind splittext. Dacă ar face ceva care să semnifice pauza dintre părțile acestui nume, ar fi mult mai ușor să recunosc că este splitExt sau split_ext. Cu siguranță nu pot fi singura persoană care a făcut această greșeală. –  > Por ArtOfWarfare.
  • @Vingtoft Nu ați menționat nimic despre FileStorage al lui werkzeug în comentariul dvs. și această întrebare nu are nimic despre acest scenariu special. S-ar putea să fie ceva în neregulă cu modul în care ți se transmite numele fișierului. os.path.splitext('somefile.ext') => ('somefile', '.ext'). Simțiți-vă liber să furnizați un contraexemplu real fără a face referire la o bibliotecă terță parte. –  > Por Gewthen.
Brian Neal
import os.path
extension = os.path.splitext(filename)[1]

Comentarii

    17

  • Din curiozitate, de ce import os.path în loc de from os import path? –  > Por kiswa.
  • Oh, mă întrebam doar dacă există un motiv anume în spatele ei (altul decât convenția). Încă învăț Python și am vrut să învăț mai mult! –  > Por kiswa.
  • 62

  • depinde de fapt, dacă folosiți from os import path atunci numele path este preluat în domeniul de aplicare local, de asemenea, alte persoane care privesc codul ar putea să nu știe imediat că path este calea din modulul os. În schimb, dacă folosiți import os.path se păstrează în cadrul domeniului os spațiu de nume și oriunde ați face apelul, oamenii știu că este vorba de path() din modulul os modul imediat. –  > Por dennmat.
  • 22

  • Știu că nu este diferit din punct de vedere semantic, dar personal găsesc construcția _, extension = os.path.splitext(filename) este mult mai frumoasă. –  > Por Tim Gilbert.
  • Dacă doriți ca extensia să facă parte dintr-o expresie mai complexă, [1] poate fi mai utilă: if check_for_gzip and os.path.splitext(filename)[1] == '.gz': –  > Por gerardw.
jeromej

Nou în versiunea 3.4.

import pathlib

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

Sunt surprins că nimeni nu a menționat pathlib încă, pathlib Este minunat!

Dacă aveți nevoie de toate sufixele (de exemplu, dacă aveți un .tar.gz), .suffixes va returna o listă cu acestea!

Comentarii

    17

  • Exemplu pentru a obține .tar.gz: ''.join(pathlib.Path('somedir/file.tar.gz').suffixes) –  > Por teichert.
  • Un răspuns excelent. Am găsit acest tutorial mai util decât documentația: zetcode.com/python/pathlib –  > Por user118967.
  • @user3780389 Un „foo.bar.tar.gz” nu ar fi totuși un „.tar.gz” valid? Dacă este așa, fragmentul tău ar trebui să folosească .suffixes[-2:] pentru a se asigura că primește cel mult .tar.gz. –  > Por jeromej.
  • există încă cazuri în care acest lucru nu funcționează conform așteptărilor, cum ar fi "filename with.a dot inside.tar". Aceasta este soluția pe care o folosesc în prezent: "".join([s for s in pathlib.Path('somedir/file.tar.gz').suffixes if not " " in s]) –  > Por eadmaster.
wonzbak
import os.path
extension = os.path.splitext(filename)[1][1:]

Pentru a obține doar textul extensiei, fără punct.

Comentarii

  • Aceasta va returna gol pentru ambele nume de fișiere care se termină cu . cât și pentru numele de fișiere fără extensie. –  > Por user202729.
Murat Çorlu

Pentru cazuri de utilizare simple, o opțiune poate fi împărțirea de la punct:

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

Nicio eroare atunci când fișierul nu are o extensie:

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

Dar trebuie să fiți atenți:

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

De asemenea, nu va funcționa cu fișiere ascunse în sistemele Unix:

>>> ".bashrc".split(".")[-1]
'bashrc'    # But this is not an extension

Pentru utilizare generală, preferați os.path.splitext

Comentarii

  • Acest lucru s-ar putea supăra dacă încărcați x.tar.gz –  > Por Kirill.
  • 19

  • De fapt, nu. Extensia unui fișier numit „x.tar.gz” este „gz”, nu „tar.gz”. os.path.splitext dă și el „.os” ca extensie. –  > Por Murat Çorlu.
  • putem folosi [1] în loc de [-1]. Nu am putut înțelege [-1] cu split –  > Por user765443.
  • [-1] pentru a obține ultimul element din elementele care au fost împărțite prin punct. Exemplu: "my.file.name.js".split('.') => ['my','file','name','js] –  > Por Murat Çorlu.
  • @BenjaminR ah ok, faci o optimizare cu privire la lista de rezultate. ['file', 'tar', 'gz'] cu 'file.tar.gz'.split('.') vs ['file.tar', 'gz'] cu 'file.tar.gz'.rsplit('.', 1). da, ar putea fi. –  > Por Murat Çorlu.
blented

merită să adaugi un lower acolo ca să nu te trezești întrebându-te de ce nu apar JPG-urile în listă.

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

yamex5

Oricare dintre soluțiile de mai sus funcționează, dar pe linux am constatat că există o linie nouă la sfârșitul șirului de extensii care va împiedica succesele de potrivire. Adăugați strip() la sfârșit. De exemplu:

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

Comentarii

  • Pentru a mă ajuta să înțeleg mai bine, vă rog să îmi explicați care este comportamentul suplimentar împotriva căruia se protejează al doilea index/slice? (de exemplu [1:] în .splittext(filename)[1][1:]) – vă mulțumesc anticipat –  > Por Samuel Harmer.
  • Mi-am dat seama singur: splittext() (spre deosebire de cazul în care împărțiți un șir de caractere folosind ‘.’) include caracterul ‘.’ în extensie. În plus [1:] scapă de el. –  > Por Samuel Harmer.
r3t40

Puteți găsi câteva lucruri grozave în modulul pathlib (disponibil în python 3.x).

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

# Output 
'.txt'

Comentarii

  • Utilizarea PosixPath pentru o cale de acces Windows este greșită. –  > Por Lior Elbaz.
XavierCLL

Cu splitext există probleme cu fișierele cu extensie dublă (de ex. file.tar.gz, file.tar.bz2, etc…)

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

dar ar trebui să fie: .tar.gz

Soluțiile posibile sunt aici

Comentarii

  • faceți-o de două ori pentru a obține cele 2 extensii ? –  > Por maazza.
  • @maazza yep. gunzip somefile.tar.gz care este numele fișierului de ieșire? –  > Por FlipMcF.
  • Acesta este motivul pentru care avem extensia ‘tgz’ care înseamnă: tar+gzip ! 😀 –  > Por Nuno Aniceto.
  • @FlipMcF Numele fișierului ar trebui să fie în mod evident somefile.tar. Pentru tar -xzvf somefile.tar.gz numele fișierului ar trebui să fie somefile. –  > Por peterhil.
  • @peterhil Nu cred că vrei ca scriptul tău python să fie conștient de aplicația folosită pentru a crea numele fișierului. Este un pic în afara domeniului de aplicare a întrebării. Nu vă luați de exemplu, „nume_filen.csv.gz” este, de asemenea, destul de valid. –  > Por FlipMcF.
weiyixie

Deși este un subiect vechi, dar mă întreb de ce nu se menționează o api foarte simplă de python numită rpartition în acest caz:

pentru a obține extensia unei anumite căi absolute a unui fișier, puteți tasta pur și simplu:

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

exemplu:

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

vă va da: ‘csv’

Comentarii

  • Pentru cei care nu sunt familiarizați cu API-ul, rpartition returnează un tupluplu: ("string before the right-most occurrence of the separator", "the separator itself", "the rest of the string"). Dacă nu se găsește niciun separator, tupla returnată va fi: ("", "", "the original string"). –  > Por Nickolay.
Alex

Doar join toate 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'

PascalVKooten

Surprins că nu s-a menționat încă:

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

Beneficii:

  • Funcționează așa cum era de așteptat pentru tot ceea ce mă pot gândi
  • Fără module
  • Fără regex
  • Cross-platform
  • Ușor de extins (de exemplu, fără puncte de început pentru extensie, doar ultima parte a extensiei)

Ca funcție:

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

Comentarii

  • Acest lucru duce la o excepție atunci când fișierul nu are nicio extensie. –  > Por thiruvenkadam.
  • Acest răspuns ignoră absolut o variantă dacă un nume de fișier conține multe puncte în nume. Exemplu get_extension(‘cmocka-1.1.0.tar.xz’) => ‘.1.0.tar.xz’ – greșit. –  > Por PADYMKO.
  • @PADYMKO, IMHO nu ar trebui să se creeze nume de fișiere cu puncte de suspensie ca parte a numelui de fișier. Codul de mai sus nu ar trebui să aibă ca rezultat ‘tar.xz’ –  > Por Douwe van der Leest.
  • Schimbați doar în [-1] apoi. –  > Por PascalVKooten.
soheshdoshi

Puteți folosi un split pe un filename:

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

Acest lucru nu necesită o bibliotecă suplimentară

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

Comentarii

  • Acest lucru are ca rezultat că ultimul caracter din filename este returnat dacă numele de fișier nu are . deloc. Acest lucru se datorează faptului că rfind returnează -1 în cazul în care șirul nu este găsit. –  > Por mattst.
Kenstars

Aceasta este o tehnică de reprezentare directă a șirurilor de caractere :Văd o mulțime de soluții menționate, dar cred că majoritatea se uită la split.Split face însă acest lucru la fiecare apariție a lui „.” .Ceea ce ar trebui să căutați mai degrabă este partiția.

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

Comentarii

  • rpartition a fost deja sugerat de @weiyixie. –  > Por Nickolay.
Arnaldo P. Figueira Figueira

O altă soluție cu right split:

# 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])

Micha

Chiar dacă această întrebare are deja răspuns, aș adăuga soluția în Regex.

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

Comentarii

  • Sau .[0-9a-z]+$ ca în această postare. –  > Por pault.
Victor Wang

Un adevărat one-liner, dacă vă place regex. Și nu contează nici dacă aveți în plus „.” la mijloc

import re

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

Vedeți aici rezultatul: Faceți clic aici

Ibnul Husainan

încercați asta:

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. obține toate numele de fișier din interiorul listei
  2. divizarea numelui de fișier și verificați penultima extensie, este sau nu în lista pen_ext?
  3. dacă da, atunci uniți-o cu ultima extensie și setați-o ca extensie a fișierului
  4. în caz contrar, se pune doar ultima extensie ca extensie a fișierului.
  5. și apoi verificați

Comentarii

  • Acest lucru se întrerupe pentru o serie de cazuri speciale. A se vedea răspunsul acceptat. Este o reinventare a roții, doar că într-un mod eronat. –  > Por Robert.
  • Bună ziua! În timp ce acest cod poate rezolva întrebarea, includerea unei explicații despre cum și de ce rezolvă problema ar ajuta cu adevărat la îmbunătățirea calității mesajului dvs. și, probabil, ar duce la mai multe voturi pozitive. Nu uitați că răspundeți la întrebare pentru cititorii din viitor, nu doar pentru persoana care o pune acum. Vă rugăm să vă editați răspunsul pentru a adăuga explicații și pentru a da o indicație cu privire la limitările și ipotezele care se aplică. –  > Por Brian.
  • @Brian așa? –  > Por Ibnul Husainan.
  • Nu faci decât să înrăutățești lucrurile, să le strici în moduri noi. foo.tar este un nume de fișier valid. Ce se întâmplă dacă arunc asta în codul tău? Ce se întâmplă cu .bashrc sau foo? Există o funcție de bibliotecă pentru asta cu un motiv anume… –  > Por Robert.
  • doar creați o listă de extensii de fișiere pentru penultima extensie, dacă nu este în listă, atunci puneți ultima extensie ca extensie a fișierului –  > Por Ibnul Husainan.
eatmeimadanish

Pentru amuzament… doar adunați extensiile într-un dict și urmăriți-le pe toate într-un dosar. Apoi, scoateți doar extensiile pe care le doriți.

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)

Comentarii

  • Asta e o idee teribilă. Codul tău se strică pentru orice extensie de fișier pe care nu ai adăugat-o anterior! –  > Por Robert.
lendoo
a = ".bashrc"
b = "text.txt"
extension_a = a.split(".")
extension_b = b.split(".")
print(extension_a[-1])  # bashrc
print(extension_b[-1])  # txt

DragonX
# 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 ""

Ripon Kumar Saha

Acesta este Cea mai simplă metodă pentru a obține atât Filename & Extensie în doar o o singură linie.

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

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

Spre deosebire de alte soluții, nu este nevoie să importați niciun pachet pentru aceasta.

Comentarii

  • acest lucru nu funcționează pentru toate fișierele sau tipurile, de exemplu ‘archive.tar.gz –  > Por studioj.
user5535053
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

wookie
name_only=file_name[:filename.index(".")

Acest lucru vă va oferi numele fișierului până la primul „.”, care ar fi cel mai comun.

Comentarii

  • în primul rând, el nu are nevoie de nume, ci de extensie. În al doilea rând, chiar dacă ar avea nevoie de nume, acesta ar fi greșit de fișiere precum: file.name.ext –  > Por ya_dimon.
  • După cum a menționat @ya_dimon, acest lucru nu va funcționa pentru numele fișierelor cu puncte. În plus, are nevoie de extensie! –  > Por Umar Dastgir.