【问题标题】:Replace all the occurrences of specific words替换所有出现的特定单词
【发布时间】:2014-10-27 05:00:52
【问题描述】:

假设我有以下句子:

bean likes to sell his beans

我想用其他词替换所有出现的特定词。例如,beanrobertbeanscars

我不能只使用str.replace,因为在这种情况下,它会将beans 更改为roberts

>>> "bean likes to sell his beans".replace("bean","robert")
'robert likes to sell his roberts'

我只需要更改整个单词,而不是另一个单词中出现的单词。我认为我可以通过使用正则表达式来实现这一点,但不知道如何正确地做到这一点。

【问题讨论】:

    标签: python regex python-2.7


    【解决方案1】:

    如果你使用正则表达式,你可以用\b指定单词边界:

    import re
    
    sentence = 'bean likes to sell his beans'
    
    sentence = re.sub(r'\bbean\b', 'robert', sentence)
    # 'robert likes to sell his beans'
    

    这里 'beans' 没有改变(改为 'roberts'),因为末尾的 's' 不是单词之间的边界:\b 匹配空字符串,但 在单词的开头或结尾。

    完整性的第二次替换:

    sentence = re.sub(r'\bbeans\b', 'cars', sentence)
    # 'robert likes to sell his cars'
    

    【讨论】:

    • 我想括号不是必需的,它们只是使正则表达式更具可读性(至少对我而言)。
    • 由于某种原因,这似乎并没有出现美国的所有情况
    【解决方案2】:

    我知道它已经很久了,但这看起来更优雅吗? :

    reduce(lambda x,y : re.sub('\\b('+y[0]+')\\b',y[1],x) ,[("bean","robert"),("beans","cars")],"bean likes to sell his beans")
    

    【讨论】:

      【解决方案3】:

      如果您一次替换一个单词,您可能会多次替换单词(而不会得到您想要的)。为避免这种情况,您可以使用函数或 lambda:

      d = {'bean':'robert', 'beans':'cars'}
      str_in = 'bean likes to sell his beans'
      str_out = re.sub(r'\b(\w+)\b', lambda m:d.get(m.group(1), m.group(1)), str_in)
      

      这样,一旦beanrobert 替换,就不会再被修改(即使robert 也在您的输入单词列表中)。

      按照 georg 的建议,我使用 dict.get(key, default_value) 编辑了这个答案。 替代解决方案(georg 也建议):

      str_out = re.sub(r'\b(%s)\b' % '|'.join(d.keys()), lambda m:d.get(m.group(1), m.group(1)), str_in)
      

      【讨论】:

      • 如果您将\bbeans?\b 用于正则表达式并使用m.group(0)(对于整个比赛) 在 lambda 中。
      • 我希望这足够通用,因此 1 个正则表达式可以处理任何输入文本 + 任何要替换的单词列表。所以我不想在我的正则表达式中使用beans
      • 我明白了。只是它会检查每一个单词,我相信这是主要的瓶颈。
      • 我同意每个单词硬编码 1 个正则表达式来替换应该更快。但是仍然存在确保一个词一旦被替换,就不会被另一个正则表达式再次替换的问题。
      • 不,这个问题不再是问题。 \bbeans?\bbeanbeans 匹配,因此您在 lambda 中得到的是 d['bean']d['beans'],因此两者的处理方式不同。
      【解决方案4】:
      "bean likes to sell his beans".replace("beans", "cars").replace("bean", "robert")
      

      将所有“beans”实例替换为“cars”,将“bean”替换为“robert”。这是因为.replace() 返回原始字符串的修改实例。因此,您可以分阶段进行思考。它基本上是这样工作的:

       >>> first_string = "bean likes to sell his beans"
       >>> second_string = first_string.replace("beans", "cars")
       >>> third_string = second_string.replace("bean", "robert")
       >>> print(first_string, second_string, third_string)
      
       ('bean likes to sell his beans', 'bean likes to sell his cars', 
        'robert likes to sell his cars')
      

      【讨论】:

      • 在实际任务中我不能这样做,因为这个替换的顺序是不确定的
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-05-19
      • 2011-11-26
      • 1970-01-01
      • 2022-01-24
      • 1970-01-01
      • 2022-12-11
      相关资源
      最近更新 更多