2

我正在寻找一些关于如何完成这些任务的想法:

  • 允许第一次出现problem_word,但禁止任何后续使用它和其余的问题词。
  • 不修改原始文档(.txt 文件)。仅针对 print() 进行修改。
  • 保持电子邮件的相同结构。如果有换行符、制表符或奇怪的间距,让它们保持完整性。

这是代码示例:

import re

# Sample email is "Hello, banned1. This is banned2. What is going on with
# banned 3? Hopefully banned1 is alright."
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']


# TODO: Filter negative_words into overused_negative_words
banned_problem_words = []
for w in problem_words:
    if sample_email.count(f'\\b{w}s?\\b') > 1:
        banned_problem_words.append(w)


pattern = '|'.join(f'\\b{w}s?\\b' for w in banned_problem_words)


def list_check(email, pattern):
    return re.sub(pattern, 'REDACTED', email, flags=re.IGNORECASE)


print(list_check(sample_email, pattern))
# Result should be: "Hello, banned1. This is REDACTED. What is going on with
# REDACTED? Hopefully REDACTED is alright."
4

1 回答 1

2

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不支持正则表达式,但无需计算)

于 2020-04-16T19:54:48.917 回答