当替换字符串的大小与子字符串不同时,使用切片替换所有出现的子字符串

Replace all occurrences of the substring using slicing when size of replacement string the differs from substring

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

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').

我该如何解决这个问题?

您正在覆盖同一个 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