Python'da dosya adından uzantı çıkarma


Yanıtlar:


1990

Evet. Kullanım os.path.splitext(bkz. Python 2.X belgeleri veya Python 3.X belgeleri ):

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

En kılavuzu dizisi bölme girişimi farklı olarak, os.path.splitextdoğru bir şekilde tedavi edecek /a/b.c/dbir uzantısı olan yerine uzantısına sahip olarak .c/dve bu tedavi edecek .bashrcyerine sahip olan uzantısının bir uzantısı sahip olarak .bashrc:

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

15
kullanımı basenamebiraz kafa karıştırıcı beri os.path.basename("/path/to/somefile.ext")dönecekti"somefile.ext"
Jiaaro

17
olmaz endswith()daha taşınabilir ve pythonic olamaz?
Sebastian Mach

79
@ klingt.net Peki, bu durumda, .asdgerçekten uzantısı !! Bu konuda düşünüyorsanız, foo.tar.gzbir olan gzip-sıkıştırılmış dosya ( .gzbir olur) tar dosyasını ( .tar). Ama ilk etapta bir gzip dosyası . Çift uzantıyı geri döndürmesini hiç beklemezdim.
nosklo

159
Standart Python işlev adlandırma kuralı gerçekten sinir bozucu - neredeyse her yeniden baktığımda, bunu olduğu gibi yanlıyorum splittext. Onlar sadece bu isim parçaları arasındaki mola belirtmek için her şeyi yaparım, o öyle olduğunu kabul etmek daha kolay olurdu splitExtya split_ext. Şüphesiz bu hatayı yapan tek kişi ben olamam?
ArtOfWarfare

9
@Vingtoft Yorumunuzda werkzeug'un FileStorage'ı hakkında hiçbir şey söylemediniz ve bu sorunun o senaryo hakkında hiçbir şeyi yok. Dosya adından nasıl geçtiğinizle ilgili bir sorun olabilir. os.path.splitext('somefile.ext')=> ('somefile', '.ext'). Bazı üçüncü taraf kitaplıklarına başvurmadan gerçek bir karşı örnek sunmaktan çekinmeyin.
Gewthen

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

15
Meraktan, neden import os.pathyerine from os import path?
kiswa

2
Ah, arkasında sadece (konvansiyon dışında) belirli bir neden olup olmadığını merak ediyordum. Hala Python öğreniyorum ve daha fazlasını öğrenmek istedim!
kiswa

55
gerçekten bağlıdır, eğer kullanırsanız, from os import patho zaman ad pathyerel kapsamınıza alınır, ayrıca koda bakan diğerleri yolun os modülünden yol olduğunu hemen bilemeyebilir. Nerede kullanmak sanki import os.patho hapseden osad ve arama yapmak yerde insanlar biliyorum path()dan oshemen modülü.
dennmat

18
Anlamsal olarak farklı olmadığını biliyorum, ama şahsen inşaatın _, extension = os.path.splitext(filename)daha hoş görüneceğini düşünüyorum .
Tim Gilbert

3
Uzantıyı daha karmaşık bir ifadenin parçası olarak istiyorsanız [1] daha yararlı olabilir: if check_for_gzip and os.path.splitext(filename)[1] == '.gz':
gerardw

239

3.4 sürümündeki yenilikler.

import pathlib

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

pathlibHenüz kimsenin bahsetmediğine şaşırdım , pathlibharika!

Tüm soneklere ihtiyacınız varsa (örneğin a varsa .tar.gz), .suffixesbunların bir listesini döndürür!


12
.tar.gz almak için örnek:''.join(pathlib.Path('somedir/file.tar.gz').suffixes)
user3780389

Mükemmel cevap. Bu eğitimi dokümantasyondan daha kullanışlı buldum: zetcode.com/python/pathlib
user118967

@ user3780389 "foo.bar.tar.gz" geçerli bir ".tar.gz" olmaz mı? Öyleyse snippet'iniz .suffixes[-2:]yalnızca .tar.gz almayı sağlamak için kullanıyor olmalıdır .
jeromej

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

Nokta olmadan uzantının metnini almak için.


73

Bir seçenek noktadan ayrılıyor olabilir:

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

Dosyanın uzantısı yoksa hata yok:

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

Ancak dikkatli olmalısınız:

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

4
X.tar.gz
Kirill

19
Aslında değil. "X.tar.gz" adlı bir dosyanın uzantısı "tar.gz" değil, "gz" dir. os.path.splitext uzantısı olarak ".os" da verir.
Murat Çorlu

1
[-1] yerine [1] kullanabilir miyiz? Split ile [-1] anlayamadım
user765443 21:13

7
[-1] noktaya bölünmüş öğelerin son öğesini almak için. Örnek:"my.file.name.js".split('.') => ['my','file','name','js]
Murat Çorlu

1
@BenjaminR ah tamam, sonuç listesi hakkında bir optimizasyon yapıyorsunuz. ['file', 'tar', 'gz']ile 'file.tar.gz'.split('.') vs ['file.tar', 'gz'] ile 'file.tar.gz'.rsplit('.', 1). evet olabilir.
Murat Çorlu

40

orada daha düşük bir değer eklemeye değer, böylece JPG'lerin neden listenizde görünmediğini merak etmiyorsunuz.

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

19

Yukarıdaki çözümlerden herhangi biri çalışır, ancak linux'da uzatma dizesinin sonunda eşleşmelerin başarılı olmasını engelleyecek yeni bir satır olduğunu gördüm. strip()Yöntemi sonuna ekleyin . Örneğin:

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

1
Anlayışıma yardımcı olmak için, lütfen ikinci endeksin / dilimin hangi ek davranışa karşı koruduğunu açıklayabilir misiniz? (yani [1:]içinde .splittext(filename)[1][1:]) - şimdiden teşekkür ederim
Samuel Harmer

1
Kendim için anladım: splittext()('.' Kullanarak bir dizeyi bölmekten farklı olarak) '.' karakter. Ek [1:]bundan kurtulur.
Samuel Harmer

17

Splitext ile çift uzantılı dosyalarla sorunlar var (örneğin file.tar.gz, file.tar.bz2vb ..)

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

ancak şöyle olmalıdır: .tar.gz

Olası çözümler burada


35
Hayır .gz olmalı
Robert Siemer

1
2 uzantı almak için iki kez yapın?
maazza

1
@maazza yep. gunzip somefile.tar.gz çıktı dosya adı nedir?
FlipMcF

1
Bu yüzden 'tgz' uzantısına sahibiz, yani tar + gzip! : D
Nuno Aniceto

1
@peterhil Python betiğinizin dosya adını oluşturmak için kullanılan uygulamanın farkında olmasını istediğinizi sanmıyorum. Sorunun kapsamı biraz dışında. Örneği seçmeyin, 'dosyaadı.csv.gz' de oldukça geçerlidir.
FlipMcF

16

Pathlib modülünde bazı harika şeyler bulabilirsiniz (python 3.x'te mevcuttur).

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

# Output 
'.txt'

14

Eski bir konu olmasına rağmen, neden bu durumda rpartition adlı python'un çok basit bir API'sinden bahsetmediğini merak ediyorum:

belirli bir dosya mutlak yolunun uzantısını almak için şunları yazabilirsiniz:

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

misal:

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

size verecek: 'csv'


1
API'ye aşina olmayanlar için rpartition bir tuple: döndürür ("string before the right-most occurrence of the separator", "the separator itself", "the rest of the string"). Bulunamadı ayırıcı varsa, iade tuple olacaktır: ("", "", "the original string").
Nickolay

13

Sadece joinhepsi 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

Şaşırmadım, henüz bahsedilmedi:

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

Yararları:

  • Aklıma gelen her şey için beklendiği gibi çalışıyor
  • Modül yok
  • Normal ifade yok
  • Platformlar arası
  • Kolayca genişletilebilir (örneğin uzatma için ön nokta yok, uzantının yalnızca son kısmı)

Fonksiyon olarak:

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

1
Bu, dosyanın herhangi bir uzantısı olmadığında bir istisna ile sonuçlanır.
thiruvenkadam

4
Bir dosya adı adında çok sayıda nokta içeriyorsa, bu yanıt bir varyantı kesinlikle yok sayar. Örnek get_extension ('cmocka-1.1.0.tar.xz') => '.1.0.tar.xz' - yanlış.
PADYMKO

@PADYMKO, IMHO dosya adının bir parçası olarak tam duraklı dosya adları oluşturmamalıdır. Yukarıdaki kodun 'tar.xz' ile sonuçlanmaması gerekiyor
Douwe van der Leest

2
Sadece [-1]o zaman değiştirin .
PascalVKooten

11

A splitüzerinde şunları kullanabilirsiniz filename:

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

Bu ek kitaplık gerektirmez


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

2
Bu filename, dosya adında hiç yoksa son döndürme karakterine neden olur .. Bunun nedeni , dize bulunamazsa rfinddöndürür -1.
mattst

6

Bu doğrudan bir dize temsil teknikleri: Bahsedilen birçok çözüm görüyorum, ama bence çoğu bölünmeye bakıyor. Ancak Split bunu her "." . Aramak istediğiniz şey bölmedir.

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

2
rpartition zaten tarafından önerildi @weiyixie .
Nickolay

5

Doğru bölünmüş başka bir çözüm:

# 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

Bu soru bile cevaplanmış olsa bile çözümü Regex'e eklerdim.

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

1
Veya bu yazıda\.[0-9a-z]+$ olduğu gibi .
Mart'ta

2

Eğer regex isterseniz, gerçek bir tek astar. Ve ek "." Kodunuz olsa bile önemli değil. ortada

import re

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

Sonuç için buraya bakın: Buraya tıklayın


0

Bu, hem Dosya Adını hem de Uzantıyı tek bir satırda elde etmenin en basit yöntemidir .

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

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

Diğer çözümlerin aksine, bunun için herhangi bir paket almanıza gerek yoktur.


2
bu tüm dosyalar veya türler için çalışmaz, örneğin 'archive.tar.gz
studioj

0

Eğlenceler için ... uzantıları bir dikte halinde toplayın ve hepsini bir klasörde takip edin. Ardından istediğiniz uzantıları çekin.

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)

Bu korkunç bir fikir. Daha önce eklemediğiniz dosya uzantıları için kodunuz kesiliyor!
Robert

0

bunu dene:

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. listenin içindeki tüm dosya adlarını al
  2. dosya adını bölme ve sondan bir önceki uzantıyı kontrol etme, pen_ext listesinde mi yoksa değil mi?
  3. evet ise, son uzantıyla birleştirin ve dosyanın uzantısı olarak ayarlayın
  4. değilse, son uzantıyı dosyanın uzantısı olarak ekleyin
  5. ve sonra kontrol et

1
Bu, bir dizi özel durum için kırılır. Kabul edilen cevaba bakınız. Tekerleği yeniden icat ediyor, sadece arabasıyla.
Robert

cevabımı güncelledim
Ibnul Husainan

Merhaba! Bu kod soruyu çözebilir, ancak bunun sorunun nasıl ve neden çözüldüğüne dair bir açıklama da dahil olmak üzere , yayınınızın kalitesini artırmaya yardımcı olabilir ve muhtemelen daha fazla oyla sonuçlanır. Sadece şimdi soran kişi için değil, gelecekte okuyucular için soruyu cevapladığınızı unutmayın. Lütfen açıklama eklemek için yanıtınızı düzenleyin ve hangi sınırlamaların ve varsayımların geçerli olduğunu belirtin.
Brian

@Brian gibi mi?
Ibnul Husainan

Sadece daha da kötüleşiyorsunuz, yeni yollarla kırıyorsunuz. foo.targeçerli bir dosya adı. Bunu kodunuza atarsam ne olur? Peki .bashrcya foo? Bunun için bir kütüphane işlevi var ...
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(".")

Bu size en yaygın olan ilk "." E kadar dosya adını verecektir.


1
ilk olarak, isme değil, uzantıya ihtiyacı var. İkincisi, isme ihtiyacı olsa bile, aşağıdaki gibi dosyalar tarafından yanlış olur:file.name.ext
ya_dimon

@Ya_dimon tarafından belirtildiği gibi, bu noktalı dosya adları için çalışmaz. Artı, onun uzantısına ihtiyacı var!
Umar Dastgir
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.