【问题标题】:Censoring a text string using a dictionary and replacing words with Xs. Python使用字典检查文本字符串并用 Xs 替换单词。 Python
【发布时间】:2013-05-21 17:06:25
【问题描述】:

我正在尝试制作一个简单的程序,该程序接受一串文本 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)

【问题讨论】:

  • @mata 需要详细说明吗?编程新手。
  • @mata 有疑问时..哈哈。

标签: python dictionary


【解决方案1】:

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

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)

这有利于使用正则表达式识别的各种单词边界。

【讨论】:

    【解决方案2】:

    首先,我相信你希望你的 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
    

    【讨论】:

    • 使用字典确实感觉有点尴尬。谢谢。
    • 请注意,这种方法似乎会漏掉被删词的复数形式。
    • 另一个说明它也不会保留原始间距
    【解决方案3】:

    您可以使用 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',则不会被替换。

    如果你想解决这一切,你需要执行tokenisation。您可能还需要考虑大写单词。

    【讨论】:

      【解决方案4】:

      这很容易理解和清理

      def censor(text, word):
             return text.replace(word, ("*"*len(word)))
      

      【讨论】:

      • 他的第二个参数是单词列表,不是一个单词。
      • 如果您的审查词不是列表,它将不起作用。
      【解决方案5】:

      我做得更紧凑了一点:

      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"], "*")
      

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

      有什么方法可以跳过,忽略字符串中的字母和数字以外的任何内容?

      【讨论】:

        【解决方案6】:
        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'], '*')
        

        【讨论】:

        • 嗨,恭喜您的第一个答案,很高兴看到您做出贡献!请记住解释您的解决方案,以便 OP 有机会弄清楚您的解决方案为何如此。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-08-25
        • 1970-01-01
        • 1970-01-01
        • 2019-01-29
        • 2018-09-11
        • 1970-01-01
        相关资源
        最近更新 更多