Есть ли лучший способ очистки текстовых файлов с помощью Python, используя регулярное выражение?

Я пытаюсь создать сценарий для сопоставления шаблонов регулярных выражений в ряде текстовых файлов и удалить эти совпадения из файла. Прямо сейчас у меня есть следующее, которое подходит для моих целей, но я не думаю, что это эффективный способ сделать это:

import os
import re

os.chdir("/home/user1/test_files")

patterns = ['(bannana)',
            '(peaches)',
            '(apples)'
           ]

subst = ""
cwd = os.getcwd()
for filename in os.listdir(cwd):
    with open(filename, 'r', encoding = "utf8") as f:
        file = f.read()
    result = re.sub('|'.join(patterns), subst, file, re.MULTILINE)
    with open("/home/user1/output_files/" + "output_" + str(filename), 'w', encoding = "utf-8") as newfile:
        newfile.write(result)

    for pattern in patterns:
        with open('/home/user1/output_files/output_'+str(filename), 'r', encoding = "utf8") as f:
            file = f.read()
        result = re.sub(pattern, subst, file, re.MULTILINE)
        with open('/home/user1/output_files/output_'+str(filename), 'w', encoding = "utf-8") as newfile:
            newfile.write(result)

Итак, допустим, у меня есть файлgross.txt, и я хочу удалить слова apples, peaches и bannana. Приведенный выше сценарий сначала запустится и создаст выходной файл output_grocery.txt. Затем он будет перебирать список шаблонов, удаляя шаблон из файла output_grocery.txt и переписывая его после каждого прохода.

То, как я это делаю сейчас, не масштабируется. В конечном итоге мне придется запустить это на сотнях файлов, каждый из которых будет перезаписываться снова и снова в зависимости от того, сколько шаблонов регулярных выражений у меня есть. Первоначально я пытался сделать это за один раз, используя:

result = re.sub('|'.join(patterns), subst, file, re.MULTILINE)

думая, что это удалит все шаблоны из файла за один раз. Однако при этом удаляется только первый шаблон, в данном случае баннан.

Есть ли лучший и более масштабируемый способ сделать это?

По крайней мере, вы можете открыть входной файл один раз и загрузить его в свою переменную file, затем выполнить итерацию по этой файловой переменной, чтобы очистить содержимое, а затем записать ее, когда закончите. Один раз.

JNevill 14.06.2024 19:36

Пожалуйста, создайте минимальный воспроизводимый пример, включающий пример ввода, ожидаемый результат и код, который мы можем запустить (например, для начала, у меня нет /home/user1 в моей системе, поэтому os.chdir() потерпит неудачу).

wjandrea 14.06.2024 19:37

Почему вы записываете это в файл после каждого шаблона?

Gene Burinsky 14.06.2024 19:39

Кстати, это совершенно не имеет отношения к проблеме, но лучше дать имя всем значениям, которые вы используете более одного раза, например '/home/user1/output_files/output_' и 'utf8'. Хорошими именами могут быть, скажем, OUTPUT_DIR и ENCODING. См. магические числа: Википедия , ТАК

wjandrea 14.06.2024 19:54

«Однако это удаляет только первый шаблон» — я только что попробовал код для себя, но не могу воспроизвести такое поведение, но потом мне пришлось догадываться, какими могут быть данные.

wjandrea 14.06.2024 19:58
Почему в Python есть оператор "pass"?
Почему в Python есть оператор "pass"?
Оператор pass в Python - это простая концепция, которую могут быстро освоить даже новички без опыта программирования.
Некоторые методы, о которых вы не знали, что они существуют в Python
Некоторые методы, о которых вы не знали, что они существуют в Python
Python - самый известный и самый простой в изучении язык в наши дни. Имея широкий спектр применения в области машинного обучения, Data Science,...
Основы Python Часть I
Основы Python Часть I
Вы когда-нибудь задумывались, почему в программах на Python вы видите приведенный ниже код?
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
LeetCode - 1579. Удаление максимального числа ребер для сохранения полной проходимости графа
Алиса и Боб имеют неориентированный граф из n узлов и трех типов ребер:
Оптимизация кода с помощью тернарного оператора Python
Оптимизация кода с помощью тернарного оператора Python
И последнее, что мы хотели бы показать вам, прежде чем двигаться дальше, это
Советы по эффективной веб-разработке с помощью Python
Советы по эффективной веб-разработке с помощью Python
Как веб-разработчик, Python может стать мощным инструментом для создания эффективных и масштабируемых веб-приложений.
1
5
79
2
Перейти к ответу Данный вопрос помечен как решенный

Ответы 2

Ответ принят как подходящий

Расширение моего комментария. Несмотря на то, что, вероятно, есть улучшения, вам следует, по крайней мере, открывать ввод только один раз, очищать данные, а затем один раз записывать данные. Ничего из операций открытия/записи/открытия/записи/открытия/записи/открытия/записи.

import os
import re

os.chdir("/home/user1/test_files")

patterns = ['(bannana)',
            '(peaches)',
            '(apples)'
           ]

subst = ""
cwd = os.getcwd()
for filename in os.listdir(cwd):

    #open the file and place contents in `file` variable
    with open(filename, 'r', encoding = "utf8") as f:
        file = f.read()

    #iterate over your patterns, replacing the pattern with 
    #nothing and updating the `file` variable for the next 
    #pattern iteration
    for pattern in patterns:
        file = re.sub(pattern, subst, file, re.MULTILINE)

    #write the `file` variable back out
    with open("/home/user1/output_files/" + "output_" + str(filename), 'w', encoding = "utf-8") as newfile:
        newfile.write(file)

Теперь, когда логика изолирована, вы можете работать над ее улучшением, чтобы она не была циклической и обеспечивала дополнительную эффективность.

проверьте присвоение имен.

Gene Burinsky 14.06.2024 19:44

спасибо @GeneBurinsky. Зафиксированный

JNevill 14.06.2024 19:46

Это потрясающе. Время выполнения сразу же улучшилось. Спасибо!

SVill 14.06.2024 19:47

Этот:

patterns = ["(banana)", "(apples)", "(peaches)"]
result = re.sub("|".join(patterns), "", "xxbananaxxapplesxxpeachesxx")

вернусь xxxxxxxx. Так что присоединение строк к шаблону таким способом не является проблемой. Как выглядят ваши настоящие узоры? re.MULTILINE влияет на то, что делают $ и ^, что указывает на то, что вы используете один из них; возможно, вы используете их таким образом, чтобы объяснить, почему он заменяет только первое вхождение?

Другие вопросы по теме