Я пытаюсь создать сценарий для сопоставления шаблонов регулярных выражений в ряде текстовых файлов и удалить эти совпадения из файла. Прямо сейчас у меня есть следующее, которое подходит для моих целей, но я не думаю, что это эффективный способ сделать это:
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)
думая, что это удалит все шаблоны из файла за один раз. Однако при этом удаляется только первый шаблон, в данном случае баннан.
Есть ли лучший и более масштабируемый способ сделать это?
Пожалуйста, создайте минимальный воспроизводимый пример, включающий пример ввода, ожидаемый результат и код, который мы можем запустить (например, для начала, у меня нет /home/user1 в моей системе, поэтому os.chdir() потерпит неудачу).
Почему вы записываете это в файл после каждого шаблона?
Кстати, это совершенно не имеет отношения к проблеме, но лучше дать имя всем значениям, которые вы используете более одного раза, например '/home/user1/output_files/output_' и 'utf8'. Хорошими именами могут быть, скажем, OUTPUT_DIR и ENCODING. См. магические числа: Википедия , ТАК
«Однако это удаляет только первый шаблон» — я только что попробовал код для себя, но не могу воспроизвести такое поведение, но потом мне пришлось догадываться, какими могут быть данные.






Расширение моего комментария. Несмотря на то, что, вероятно, есть улучшения, вам следует, по крайней мере, открывать ввод только один раз, очищать данные, а затем один раз записывать данные. Ничего из операций открытия/записи/открытия/записи/открытия/записи/открытия/записи.
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)
Теперь, когда логика изолирована, вы можете работать над ее улучшением, чтобы она не была циклической и обеспечивала дополнительную эффективность.
проверьте присвоение имен.
спасибо @GeneBurinsky. Зафиксированный
Это потрясающе. Время выполнения сразу же улучшилось. Спасибо!
Этот:
patterns = ["(banana)", "(apples)", "(peaches)"]
result = re.sub("|".join(patterns), "", "xxbananaxxapplesxxpeachesxx")
вернусь xxxxxxxx. Так что присоединение строк к шаблону таким способом не является проблемой. Как выглядят ваши настоящие узоры? re.MULTILINE влияет на то, что делают $ и ^, что указывает на то, что вы используете один из них; возможно, вы используете их таким образом, чтобы объяснить, почему он заменяет только первое вхождение?
По крайней мере, вы можете открыть входной файл один раз и загрузить его в свою переменную
file, затем выполнить итерацию по этой файловой переменной, чтобы очистить содержимое, а затем записать ее, когда закончите. Один раз.