Аргумент repl
для re.sub
может принимать функцию, которая принимает объект соответствия и возвращает строку замены. Вот мое решение:
import re
sample_email = open('email.txt', 'r').read()
# First use of any of these words is allowed; those following are banned
problem_words = ['banned1', 'banned2', 'banned3']
pattern = '|'.join(f'\\b{w}\\b' for w in problem_words)
occurrences = 0
def redact(match):
global occurrences
occurrences += 1
if occurrences > 1:
return "REDACTED"
return match.group(0)
replaced = re.sub(pattern, redact, sample_email, flags=re.IGNORECASE)
print(replaced)
(Как еще примечание, string.count
не поддерживает регулярное выражение, но нет необходимости считать)