Как избавиться от расширений из файла basename с помощью python

У меня есть полный путь к файлам в списке:

a = ['home/robert/Documents/Workspace/datafile.xlsx', 'home/robert/Documents/Workspace/datafile2.xls', 'home/robert/Documents/Workspace/datafile3.xlsx']

я хочу получить только файлы NAMES без их расширений, например:

b = ['datafile', 'datafile2', 'datafile3']

Я пробовал:

xfn = re.compile(r'(\.xls)+')
for name in a:
    fp, fb = os.path.split(fp)
    ofn = xfn.sub('', name)
    b.append(ofn)

Но это приводит к:

b = ['datafilex', 'datafile2', 'datafile3x']

Ответ 1

  • Регулярное выражение, которое вы использовали, неверно. (\.xls)+ соответствует строкам формы .xls, .xls.xls и т.д. Вот почему в .xlsx есть оставшийся x. Вы хотите \.xls.*, т.е. A .xls, за которым следуют ноль или более любых символов.

  • Вам не нужно использовать регулярное выражение. В os.path есть специальные методы: basename и splitext.

    >>> import os.path
    >>> os.path.basename('home/robert/Documents/Workspace/datafile.xlsx')
    'datafile.xlsx'
    >>> os.path.splitext(os.path.basename('home/robert/Documents/Workspace/datafile.xlsx'))[0]
    'datafile'
    

    поэтому, если вы действительно не заботитесь о суффиксе .xls/.xlsx, ваш код может быть таким же простым, как:

    >>> a = ['home/robert/Documents/Workspace/datafile.xlsx', 'home/robert/Documents/Workspace/datafile2.xls', 'home/robert/Documents/Workspace/datafile3.xlsx']
    >>> [os.path.splitext(os.path.basename(fn))[0] for fn in a]
    ['datafile', 'datafile2', 'datafile3']
    

    (также обратите внимание на понимание .)

Ответ 2

Oneliner:

>>> filename = 'file.ext'
>>> '.'.join(filename.split('.')[:-1]) if '.' in filename else filename
'file'

Ответ 3

Почему бы просто не использовать метод split?

def get_filename(path):
    """ Gets a filename (without extension) from a provided path """

    filename = path.split('/')[-1].split('.')[0]
    return filename


>>> path = '/home/robert/Documents/Workspace/datafile.xlsx'
>>> filename = get_filename(path)
>>> filename
'datafile'