【问题标题】:Replace values in a string替换字符串中的值
【发布时间】:2018-04-05 16:37:39
【问题描述】:

因此,挑战是用与该单词等长的星号替换句子中的特定单词 - 3 个字母 --> 3 个星号等。

第一部分不起作用,但第二部分可以 - 任何人都可以批评第一部分并指出我可能犯的错误,因为最初的逻辑似乎是合理的?

def censor(text, word):
  for c in text:
    if c == word:                         ## this line was totally wrong
      text.replace(c, "*" * len(c))
    return text

下一部分确实有效,然后 CodeAcademy 的答案就不同了:

def censor(text, word):
  a = "*" * len(word)
  for c in text:
    nw = text.split(word)
  return a.join(nw)

您将如何处理这项任务?

【问题讨论】:

  • text 是列表还是字符串?
  • 提示。考虑代码x = "Hello"; x.replace("H", "J"); print(x)。你期望输出是什么?
  • 您的具体问题是什么(您不应该真正征求我们的意见 - 这些意见各不相同)?预期的输入和输出是什么。请查看minimal reproducible example。另外,什么值被传递到textword?您似乎正在迭代文本中的字符并将它们与单词进行比较。
  • 欢迎来到 SO。请花时间阅读How to Ask

标签: python join split


【解决方案1】:

你可以试试这个:

s = "hello, how are you?"
word = "hello"
import re
final_string = re.sub("\b"+re.escape(word)+"\b", '*'*len(word), s) 

输出:

'*****, how are you?'

【讨论】:

  • 您需要\b 左右word 才能正确匹配。另外,re.escape(word),不仅仅是文字。转义很重要,否则你会得到en.wikipedia.org/wiki/Code_injection :-)
  • @DonchoGunchev 感谢您指出这一点。我不知道 Python re 容易受到代码注入的影响
  • 可以得到RegExp注入,如果word = '.'或者word = '.*'呢?我能想到的最糟糕的是一个复杂的模式,需要几个小时才能匹配/不匹配......所以 DOS。经验法则:如果有特殊字符 - 转义它们(html、js、re、sql、you_name_it)!
【解决方案2】:

正则表达式方法很好。另一种方法是用空格分割句子,寻找要审查的词,然后用星号替换它。

def censor(sentence, word):
    return " ".join([w if w != word else "*"*len(w) for w in sentence.split(" ")])

不过,这不适用于标点符号。

【讨论】:

    【解决方案3】:

    在第一段代码中,您逐个字符地遍历字符串 - 您永远找不到单词。

    在这种情况下,我会使用正则表达式 import re 以使其更快并找到正确的单词。尝试掩盖句子The airplane is in the air now!中的“空气”一词。

    re 为例。

    re.sub(r'\bair\b', '***', 'The airplane is in the air now!', flags=re.IGNORECASE)
    

    【讨论】:

    • 是什么让您认为正则表达式会更快地完成这项任务? OP 正在做一个简单的字符串替换操作,他们不需要正则表达式。
    • 如果没有正则表达式,很难正确找到“单词”...编译的正则表达式快速且正确,但比简单(不正确的)字符串操作要慢。
    【解决方案4】:

    第二种方案也不完美:

    def censor(text, word):
      a = "*" * len(word)
      nw = text.split(word)  # no need for a loop here, one split catches all occurrences
      return a.join(nw)
    

    第一次尝试:

    def censor(text, word):
      # for c in text:  # loops char by char
      #  if c == word:  # one character likely won't be your word
      #    text.replace(c, "*" * len(c))  # does nothing, string is immutable
      return text.replace(word, "*" * len(word))  # simple!
    

    【讨论】:

    • 第一个任务在空格上拆分并在循环中进行替换可能是一个好主意,因此您不会对包含目标单词的单词执行替换,如 Doncho Gunchev 的 'air ' - '飞机' 示例。
    • 在第一部分没有意识到循环错误 - 我一定认为我仍然需要以某种方式迭代它。很高兴看到我与第一部分中的 text.replace(c, "*" * len(c)) 相差不远 - 现在我知道我正在循环遍历字符,这更有意义。谢谢!
    猜你喜欢
    • 2015-11-28
    • 2017-05-10
    • 2011-10-14
    • 1970-01-01
    • 2023-01-05
    • 2021-09-23
    • 2015-03-27
    相关资源
    最近更新 更多