Pythonでファイル名から拡張子を抽出する


回答:


1990

はい。使用os.path.splitextPython 2.XドキュメントまたはPython 3.Xドキュメントを参照):

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

ほとんどの手動の文字列分割試行とは異なり、os.path.splitext/a/b.c/dextensionの代わりに拡張子なしとして正しく処理し、extensionの代わりに拡張子なしとして.c/d扱います。.bashrc.bashrc

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

15
戻るbasenameので、ここでの使用は少し混乱しますos.path.basename("/path/to/somefile.ext")"somefile.ext"
Jiaaro

17
endswith()よりポータブルでpythonicにならないでしょうか?
セバスチャンマッハ

79
@ klingt.netまあ、その場合、.asd本当に拡張機能です!! あなたが考えてみれば、foo.tar.gzあるgzipで圧縮されたファイル.gzあることを起こる)tarファイル.tar)。ただし、そもそもgzipファイルです。デュアルエクステンションが返されるとはまったく思いません。
nosklo 2014年

160
標準のPython関数の命名規則は非常に煩わしいものです。これを再検討するたびに、私はそれをと誤解していsplittextます。彼らはちょうどこの名前の部分の間の休憩を意味する何かをするならば、それはだことを認識することがはるかに容易になるだろうsplitExtsplit_ext。きっとこの間違いをしたのは私だけではないでしょうか?
ArtOfWarfare 2015年

9
@VingtoftあなたはコメントでwerkzeugのFileStorageについて何も言及していませんでした、そしてこの質問はその特定のシナリオについて何も持っていません。ファイル名を渡す方法に問題がある可能性があります。os.path.splitext('somefile.ext')=> ('somefile', '.ext')。第三者のライブラリを参照せずに、実際の反例を気軽に提供してください。
Gewthen

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

15
好奇心から、なぜimport os.path代わりにfrom os import path
kiswa

2
ああ、その背後に(慣習以外の)特定の理由があるのか​​とただ思っていました。私はまだPythonを学んでいて、もっと学びたいと思っていました!
キスワ

55
実際に依存します。使用すると、ローカルスコープでfrom os import path名前pathが使用されます。また、コードを見ている他の人は、パスがosモジュールからのパスであることをすぐに認識できない場合があります。まるでそれを使用しimport os.pathているかのように、それをos名前空間内に保ち、どこに呼び出しを行っても、それpath()osモジュールからのものであることをすぐに人々に知らせます。
dennmat

18
私はそれが意味的に何の違いもないことを知っていますが、私は個人的に構造_, extension = os.path.splitext(filename)がはるかに見栄えが良いと感じています。
Tim Gilbert、

3
あなたは、より複雑な式の一部として拡張したい場合は、[1]は、より有用である可能性がある: if check_for_gzip and os.path.splitext(filename)[1] == '.gz':
gerardw

239

バージョン3.4の新機能。

import pathlib

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

誰もpathlibまだ言及していないことに驚いていpathlibます。すごいです!

すべてのサフィックスが必要な場合(たとえば、がある場合.tar.gz)は、.suffixesそれらのリストを返します。


12
.tar.gzを取得する例:''.join(pathlib.Path('somedir/file.tar.gz').suffixes)
user3780389 2017

すばらしい答えです。私はこのチュートリアルがドキュメントよりも便利だと感じました:zetcode.com/python/pathlib
user118967

@ user3780389「foo.bar.tar.gz」はまだ有効な「.tar.gz」ではないでしょうか?もしそうなら、あなたのスニペットは.suffixes[-2:]せいぜい.tar.gzだけを確実に取得するために使用されるべきです。
jeromej

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

ドットなしで、拡張子のテキストのみを取得します。


73

1つのオプションがドットから分割されている可能性があります。

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

ファイルに拡張子がない場合でもエラーなし:

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

ただし、注意が必要です。

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

4
これは、x.tar.gzをアップロードする場合に混乱します
Kirill

19
実際はそうではなくて。「x.tar.gz」という名前のファイルの拡張子は「tar.gz」ではなく「gz」です。os.path.splitextも拡張子として「.os」を与えます。
MuratÇorlu12年

1
[-1]ではなく[1]を使用できますか?スプリットで[-1]を理解できませんでした
user765443

7
[-1]ドットで分割されたアイテムの最後のアイテムを取得します。例:"my.file.name.js".split('.') => ['my','file','name','js]
MuratÇorlu2013

1
@BenjaminRああ、わかりました。結果リストについて最適化を行っています。を持ちます。そうかもしれない ['file', 'tar', 'gz']'file.tar.gz'.split('.') ['file.tar', 'gz']'file.tar.gz'.rsplit('.', 1)
MuratÇorlu2017

40

JPGがリストに表示されない理由を不思議に思わないように、そこに低い値を追加する価値があります。

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

19

上記の解決策はどれでも機能しますが、Linuxでは、一致が成功しないようにする拡張文字列の最後に改行があることがわかりました。strip()メソッドを最後に追加します。例えば:

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

1
私の理解を助けるために、2番目のインデックス/スライスがどのような追加の振る舞いを防ぐのか説明していただけませんか?(すなわち[1:].splittext(filename)[1][1:]) -事前にあなたに感謝
サミュエル・ハーマー

1
それを自分で考え出した:(splittext()'。'を使用して文字列を分割する場合とは異なり) '。'が含まれている 拡張子の文字。追加[1:]はそれを取り除きます。
Samuel Harmer、2011年

17

splitextダブル拡張子を持つファイルに問題がある(例えばfile.tar.gzfile.tar.bz2など。)

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

しかし: .tar.gz

可能な解決策はこちらです


35
いいえ、それは.gzである必要があります
Robert Siemer 2013年

1
2つの拡張機能を取得するために2回実行しますか?
maazza 2013年

1
@maazzaうん。 gunzip somefile.tar.gz 出力ファイル名は何ですか?
FlipMcF

1
これが、拡張子 'tgz'がある理由です。これは、tar + gzipを意味します。:D
Nuno Aniceto 2014

1
@peterhil私はあなたがあなたのpythonスクリプトにファイル名を作成するために使用されたアプリケーションを認識させたいとは思わない。質問の範囲外です。例を選択しないでください。「filename.csv.gz」も非常に有効です。
FlipMcF

16

pathlibモジュール(python 3.xで利用可能)でいくつかの素晴らしいものを見つけることができます。

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

# Output 
'.txt'

14

古いトピックですが、この場合rpartitionと呼ばれるpythonの非常に単純なAPIについて言及されていないのはなぜでしょうか。

特定のファイルの絶対パスの拡張子を取得するには、次のように入力するだけです。

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

例:

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

あなたに与える: 'csv'


1
APIに慣れていない場合、rpartitionはタプルを返します("string before the right-most occurrence of the separator", "the separator itself", "the rest of the string")。セパレータが見つからない場合、返されるタプルは次のようになります("", "", "the original string")
Nickolay 2018年

13

ただjoin全部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

これはまだ言及されていないことに驚いた:

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

利点:

  • 私が考えることができるすべてのものに対して期待どおりに機能します
  • モジュールなし
  • 正規表現なし
  • クロスプラットフォーム
  • 簡単に拡張可能(例:拡張の先頭のドットなし、拡張の最後の部分のみ)

機能として:

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

1
これにより、ファイルに拡張子がない場合は例外が発生します。
thiruvenkadam

4
ファイル名に多くのポイントが含まれている場合、この答えはバリアントを無視します。例get_extension( 'cmocka-1.1.0.tar.xz')=> '.1.0.tar.xz'-間違っています。
PADYMKO 2016

@PADYMKO、私見1つは、ファイル名の一部としてフルストップのファイル名を作成するべきではありません。上記のコードは 'tar.xz'になるはずではありません
Douwe van der Leest

2
その時だけに変更してください[-1]
PascalVKooten

11

あなたは使用することができますsplit上にfilename

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

これは追加のライブラリを必要としません


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

2
これによりfilename、ファイル名にまったく文字がない場合、最後の文字が返さ.れます。これは、文字列が見つからない場合にがrfind返さ-1れるためです。
mattst

6

これは直接的な文字列表現手法です。多くの解決策が言及されていますが、ほとんどは分割を検討していると思います。ただし、「。」が出現するたびに分割されます。。あなたが探しているのはパーティションです。

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

2
rpartitionは@weiyixieによってすでに提案されています
ニコライ

5

右分割の別のソリューション:

# 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

この質問でさえ答えられているので、Regexにソリューションを追加します。

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

1
または\.[0-9a-z]+$のように、このポスト
ポールト

2

あなたが正規表現が好きなら、真のワンライナー。また、「。」を追加しても問題ありません。途中で

import re

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

結果はこちらをご覧ください:ここをクリック


0

これは、ファイル名と拡張子の両方を1行で取得する最も簡単な方法です。

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

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

他のソリューションとは異なり、このためにパッケージをインポートする必要はありません。


2
これは、すべてのファイルまたはタイプに対して
機能しません(

0

ファンシーについては... dictで拡張機能を収集し、それらをすべてフォルダーで追跡します。次に、必要な拡張機能をプルします。

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)

それはひどい考えです。これまでに追加していないファイル拡張子があると、コードが壊れます。
ロバート

0

これを試して:

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. リスト内のすべてのファイル名を取得する
  2. ファイル名を分割し、最後から2番目の拡張子を確認します。pen_extリストにあるかどうかを確認します。
  3. はいの場合は、最後の拡張子で結合し、ファイルの拡張子として設定します
  4. そうでない場合は、最後の拡張子をファイルの拡張子として配置します
  5. そしてそれをチェックしてください

1
これは、多くの特別なケースでは機能しません。受け入れられた答えを見てください。バギーな方法でのみ、ホイールを再発明しています。
ロバート

答えを更新しました
Ibnul Husainan

こんにちは!このコードは問題を解決する可能性がありますが、これが問題を解決する方法と理由の説明含めると、投稿の品質が向上し、おそらく投票数が増えることになります。あなたが今尋ねている人だけでなく、あなたが将来の読者のための質問に答えていることを忘れないでください。回答を編集して説明を追加し、適用される制限と前提を示してください。
ブライアン

@ブライアンはそのような?
Ibnul Husainan

あなたはそれをさらに悪化させ、新しい方法でそれを壊しています。foo.tar有効なファイル名です。それをあなたのコードに投げたらどうなりますか?どう.bashrcfoo?これにはライブラリ関数があります...
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(".")

これにより、最も一般的な最初の「。」までのファイル名が得られます。


1
まず、名前ではなく拡張子が必要です。第2に、名前が必要な場合でも、次のようなファイルでは間違っていますfile.name.ext
。– ya_dimon

@ya_dimonで述べたように、これはドットを含むファイル名では機能しません。さらに、彼は延長が必要です!
Umar Dastgir、
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.