首页 > 解决方案 > 当替换字符串的大小与子字符串不同时,使用切片替换所有出现的子字符串

问题描述

我想替换字符串中出现的所有子字符串,但我不希望使用 replace 方法。这只是学习兴趣。目前,实验使我想到了这一点:

def count_substrings_and_replace(string, substring, rpl=None):
    string_size = len(string)
    substring_size = len(substring)
    rpl_size = len(rpl)
    count = 0
    for i in range(0, string_size + rpl_size):
        if string[i:i + substring_size] == substring:
            if rpl:
                string = string[:i] + rpl + string[i + substring_size:]
            count += 1
    return count, string

我发现它不适用于任何大小的rpl.

例如,count_substrings_and_replace("aaaQaaa", "aaa", "dddddd")我有输出:

(2, 'ddddddQdddddd'), 好吧

但如果rpl需要更大的尺寸,例如:count_substrings_and_replace("aaaQaaaQaaa", "aaa", "ddddddddd")我有输出:

(2, 'dddddddddQdddddddddQaaa').

我怎样才能解决这个问题?

标签: pythonstringreplacesubstring

解决方案


您正在覆盖相同的string变量,从而改变它的大小。在您的示例中,每次替换aaa为“dddddddd , your string is longer, and range(0, string_size + rpl_size)”都是过时的。

def count_substrings_and_replace(string, substring, rpl=None):
    string_size = len(string)
    substring_size = len(substring)
    rpl_size = len(rpl)

    count = 0
    i = 0
    while i < string_size:
        if string[i:i + substring_size] == substring:
            if rpl:
                string = string[:i] + rpl + string[i + substring_size:]
                string_size += rpl_size - substring_size
                # this is important to avoid replacement of substrings
                # contained in rpl, e.g. `aaa` and `aaaaaaaa`
                i += rpl_size
            count += 1
        else:
            i += 1
    return count, string

但是,如果您只是将结果存储在一个新变量中而忘记切片部分,那会容易得多。

def count_substrings_and_replace(string, substring, rpl=None):
    count = 0
    i = 0
    result = ''
    
    while i < len(string):
        if string[i:i + len(substring)] == substring:
            result += rpl
            count += 1
            i += len(substring)
        else: 
            result += string[i]
            i += 1
    return count, result

推荐阅读