代码之家  ›  专栏  ›  技术社区  ›  Amit

替换字符串中除第一个以外的所有引用

  •  3
  • Amit  · 技术社区  · 7 年前

    给定字符串:

    X做了些什么。X觉得很好,所以X回家了。

    我想替换所有出现的 X 但是第一个是Y,因此输出字符串如下所示:

    X做了些什么。你觉得很好,就回家了。

    https://vi.stackexchange.com/questions/10905/substitution-how-to-ignore-the-nth-first-occurrences-of-a-pattern

    7 回复  |  直到 7 年前
        1
  •  8
  •   Ry- Vincenzo Alcamo    7 年前

    str.partition 将字符串拆分为分隔符前面的部分、分隔符本身和后面的部分,如果分隔符不存在,则拆分为字符串和两个空字符串。归根结底是:

    s = 'X did something. X found it to be good, and so X went home.'
    before, first, after = s.partition('X')
    result = before + first + after.replace('X', 'Y')
    
        2
  •  6
  •   Dani Mesejo    7 年前

    re.sub 使用一个函数:

    import re
    
    
    def repl(match, count=[0]):
        x, = count
        count[0] += 1
        if x > 0:
            return 'Y'
        return 'X'
    
    
    print(re.sub('X', repl, 'X did something. X found it to be good, and so X went home.'))
    

    X did something. Y found it to be good, and so Y went home.
    

    这样做的目的是使用一个函数来保持数据的计数 X

        3
  •  3
  •   omri_saadon    7 年前

    另一种选择是查找第一个,并且仅在替换所有后进行 X

    最后,从句首到句首

    st = 'X did something. X found it to be good, and so X went home.'
    first_found = st.find('X')
    print (st[:first_found + 1] + st[first_found + 1:].replace('X', 'Y'))
    # X did something. Y found it to be good, and so Y went home.
    
        4
  •  2
  •   timgeb    7 年前

    这是一个没有正则表达式的低技术解决方案。:)

    >>> s = 'X did something. X found it to be good, and so X went home'
    >>> s = s.replace('X', 'Y').replace('Y', 'X', 1)
    >>> s
    >>> 'X did something. Y found it to be good, and so Y went home'
    

    解决方案如果 'Y' 可以存在于原始字符串中:

    def replace_tail(s, target, replacement):
        try:
            pos = s.index(target)
        except ValueError:
            return s
        pos += len(target)
        head = s[:pos]
        tail = s[pos:]
        return head + tail.replace(target, replacement)
    

    演示:

    >>> s = 'Today YYY and XXX did something. XXX found it to be good, and so XXX went home without YYY.'
    >>> replace_tail(s, 'XXX', 'YYY')
    >>> 'Today YYY and XXX did something. YYY found it to be good, and so YYY went home without YYY.'
    
        5
  •  1
  •   OmG    7 年前

    replace 如果可能的话。

        6
  •  1
  •   willeM_ Van Onsem    7 年前

    切片 生成两个字符串:第一个字符串直到(包括)第一个元素,下一个片段包含其余元素。然后,我们可以在该零件上应用替换零件,并将这些零件合并回:

    def replace_but_first(text, search, replace):
        try:
            idx = text.index(search) + len(search)
            return text[:idx] + text[idx:].replace(search, replace)
        except ValueError:  # we did not found a single match
            return text
    

    >>> replace_but_first('X did something. X found it to be good, and so X went home.', 'X', 'Y')
    'X did something. Y found it to be good, and so Y went home.'
    
        7
  •  0
  •   haxtar    7 年前

    如果您仍然对使用正则表达式操作感兴趣,可以使用 re.finditer() MatchObject 找到每个匹配案例的实例。将迭代器强制转换为列表允许您索引到 匹配对象 实例。在下面的函数中, [1:] 指示跳过第一个匹配。

    def replace_rest(my_string, replacement):
    
        for match in list(re.finditer(r'(X)', my_string))[1:]:
            my_string = my_string[0:match.start()] + replacement + my_string[match.end():]
    
        return my_string
    

    运行:

    >>> my_string = "Person X did something. X found it to be good, and so Y went home."
    

    输出:

    >>> replace_rest(my_string, "Y")
    'Person X did something. Y found it to be good, and so Y went home.'
    

    :这对于忽略任何第n次出现的图案也很有用。