Использование регулярных выражений для чтения файла из каталога

#python #python-3.x #regex #glob #re

Вопрос:

У меня есть каталог, состоящий из множества файлов. На каждой итерации цикла for я хочу читать файл, начинающийся с

 "stc_"   str(k)   "anything here"   "_alpha.mat"
 

Это k меняется на каждой итерации. Как я могу использовать регулярные выражения для чтения подобных файлов?

В начале есть только один файл с. "stc_" str(k) Но «здесь все что угодно» меняется от файла к файлу.

Я знаю, что один из вариантов-переписать все файлы, но я хочу научиться использовать регулярные выражения для этой цели.

Ответ №1:

Вы можете сделать это с filter помощью on os.listdir :

 import os
import re

def glob_re(pattern, strings):
    return filter(re.compile(pattern).match, strings)

filenames = glob_re(r'stc_d.*_alpha.mat', os.listdir())
 

Комментарии:

1. Большое спасибо. Затем, я думаю, мне также нужно указать значение d. Как я могу его пройти? Например, в первом цикле я хочу прочитать stc_0_ _alpha.mat, Во втором цикле stc_1_ _alpha.mat я также хочу передать значение d

2. затем просто замените d на фактическую строку, которую вы хотите. Но это кажется чрезмерно неэффективным; просто отсортируйте файлы численно.

3. …Но тогда вам вообще не нужно регулярное выражение.

Ответ №2:

Вы не раскрыли домен k , но, судя по комментариям, это, похоже, число.

Если для каждого есть только один файл k , вы можете просто просмотреть их.

 for knum in range(kmin, kmax 1):
     for file in glob.glob("stc_%i*_alpha.mat" % knum):
        # Only expect one match
        process(file)
 

Если вы действительно одержимы использованием регулярного выражения для этого, регулярное выражение для чисел с 7 по 24 просто (?:7|8|9|10|11|...|23|24) (его можно было бы упростить (?:[7-9]|1[0-9]|2[0-4]) , но здесь, вероятно, это не стоит усилий).

os.listdir вернет соответствующие файлы, отсортированные в алфавитном порядке; если вам требуется другой порядок сортировки, возможно, используйте os.scandir и предоставьте свою собственную функцию сортировки.

 my_files = []
for file in os.scandir(directory):
    m = re.match(r'stc_(d ).*_alpha.mat', file)
    if m:
        # Maybe you only care about a particular range for k?
        kcurr = int(m.group(1))
        if kcurr < 7 or kcurr > 24:
            continue
        my_files.append(kcurr, file))
my_files = [x[1] for x in sorted(my_files)]
 

Здесь мы используем круглые скобки группирования регулярных выражений для извлечения кортежа, содержащего ключ сортировки и имя файла, а затем отбрасываем ключи сортировки после сортировки, сохраняя только отсортированный список соответствующих файлов. (См. также преобразование Шварца.)

if Предложение, которое пропускает значения ниже 7 или больше 24, демонстрирует, как охватывать только определенные числа; если вам это не нужно, очевидно, уберите его.

Попадание на диск происходит примерно в 1000 раз медленнее, чем обработка данных в памяти, поэтому, как правило, вы хотите избежать повторного доступа к диску.