1

我正在尝试制作一个简单的程序,它采用一串文本t和一个单词列表l并打印文本,但将l中的单词替换为与单词中的字母相对应的多个 X。

问题:我的代码还替换了与l中的单词匹配的部分单词。我怎样才能让它只针对整个单词?

def censor(t, l):

    for cenword in l:
        number_of_X = len(cenword)
        sensurliste = {cenword : ("x"*len(cenword))}

        for cenword, x in sensurliste.items():
            word = t.replace(cenword, x)
            t = word.replace(cenword, x)

    print (word)
4

6 回答 6

2

另一种方法是使用正则表达式来获取所有单词:

import re

blacklist = ['ccc', 'eee']

def replace(match):
    word = match.group()
    if word.lower() in blacklist:
        return 'x' * len(word)
    else:
        return word

text = 'aaa bbb ccc. ddd eee xcccx.'

text = re.sub(r'\b\w*\b', replace, text, flags=re.I|re.U)
print(text)

这具有使用正则表达式识别的各种单词边界的优势。

于 2013-05-21T17:40:35.533 回答
1

首先,我相信你希望你的 for 循环处于同一级别,这样当一个完成另一个开始时。

其次,看起来你有额外的代码,实际上并没有做任何事情。

例如,sensurliste只会有被审查的词,与“X”字符串配对。因此不需要第一个 for 循环,因为在第二个 for 循环中当场创建“X”字符串是微不足道的。

然后,你说 word = t.replace(cenword,x) t=word.replace(cenword,x)

第二行什么都不做,因为word已经替换了所有 cenword 的实例。所以,这可以缩短为

t = t.replace(cenword,x);

最后,这是您的问题所在,python replace 方法不关心单词边界。所以无论它是否是一个完整的单词,它都会替换 cenword 的所有实例。

您可以使用正则表达式来制作它,因此它只会找到完整单词的实例,但是,我只会使用更多类似的东西

def censort(t,l):
    words = t.split()                       #split the words into a list
    for i in range(len(words)):             #for each word in the text
        if words[i] in l:                       #if it needs to be censoredx
            words[i] = "X"*len(words[i])            #replace it with X's
    t=words.join()                          #rejoin the list into a string
于 2013-05-21T17:21:51.837 回答
0

this is very easy to understand and clean

def censor(text, word):
       return text.replace(word, ("*"*len(word)))
于 2014-08-13T17:47:29.793 回答
0

您可以使用 RegExp(模块 re)进行替换,也可以将输入字符串拆分为您认为的“整个单词”。

如果您将任何分隔的空格视为一个单词,则可以执行以下操作:

def censor(t, l):
    for cenword in l:
        number_of_X = len(cenword)
        sensurliste = {cenword : ("x"*len(cenword))}
    censored = []
    for word in t.split():
        append(sensurliste.get(word, word))
    return ' '.join(censurliste)

请注意,这不会保留原始间距。此外,如果您的文本包含标点符号,这可能不会产生您认为应该的结果。例如,如果t包含单词 'stupid!',但列表只有 'stupid',则不会被替换。

如果您想解决所有这些问题,您将需要执行标记化。您可能还必须考虑大写单词。

于 2013-05-21T17:31:02.090 回答
0

我做得更紧凑一点:

def censor_string(text, banned_words, replacer):
    return "".join([x + " " if x.lower() not in banned_words else replacer*len(x) + " " for x in text.split(" ") ])

但是我遇到了像“?”这样的特殊标志的问题。或昏迷。如果我将运行以下功能:

censor_string("Today is a Wednesday!", ["is", "Wednesday"], "*")

我收到的是“今天**一个星期三!” 而不是“今天**一个********!”

任何死亡如何跳过,忽略字符串中的字母和数字以外的任何内容?

于 2020-03-02T18:42:32.757 回答
0
def censor_string(text, censorlst, replacer):

    word_list = text.split()
    for censor in censorlst:
        index = 0
            for word in word_list:
            if censor.lower() == word.lower():
                ch = len(censor) * replacer
                word_list[index] = ch
            elif censor.lower() == word[0:-1].lower():
                ch = len(censor) * replacer
                word_list[index] = ch+word[-1]
            index+=1

return " ".join(word_list)
censor_string('Today is a Wednesday!', ['Today', 'a'], '-')
censor_string('The cow jumped over the moon.', ['cow', 'over'], '*')
censor_string('Why did the chicken cross the road?', ['Did', 'chicken','road'], '*')
于 2021-05-15T19:10:59.240 回答