有没有办法替换字符串中的不同值?

Is there a way to replace diferent values in a string?

所以我想用罗马数字替换普通数字,但只替换了最后一个数字,所以我想知道是否有办法替换不同的值

sample = "Carl 5, 19 century"
numbers = re.findall(r'[0-9]+', sample)
for number in numbers:
    num_int = int(number)
    roman_number = int_to_Roman(num_int)
    new_string = sample.replace(number, roman_number)

>>> Carl 5, XIX century

这是其他一些结果

sample = "Carl 19, 19 century"
>>> Carl XIX, XIX century

sample = "Carl 5"
>>> Carl V

代码中的以下行采用原始字符串 sample 并将 number 替换为 roman_number,但它存储在变量 new_string 中。在下一次迭代中,代码将再次获取原始字符串(没有存储上一次迭代的替换)并将 number 替换为 roman_number 这就是为什么在打印 [=17= 时] 循环后,它只是显示最后一个被替换的数字(这是循环最后一次迭代中的替换)。

new_string = sample.replace(number, roman_number)

对此有 2 个修复。一种是将修改后的字符串存储在样本变量本身中,以便循环可以获取上一次迭代的结果并进行进一步的替换。

sample = sample.replace(number, roman_number)

如果想保留原来的变量sample,可以在循环之前创建变量的副本,对new_string变量做替换操作

sample = "Carl 5, 19 century"
numbers = re.findall(r'[0-9]+', sample)
new_string = sample
for number in numbers:
    num_int = int(number)
    roman_number = int_to_Roman(num_int)
    new_string = new_string.replace(number, roman_number)

编辑:

正如 tdelaney 所指出的,较大数字中较小的数字部分也可以被替换(例如 5 in 15)。要解决此问题,请按相反顺序对数字进行排序(首先是较大的数字)

numbers = re.findall(r'[0-9]+', sample)
numbers = sorted(numbers, reverse=True, key=len)

您可以使用 re.sub() 并将可调用(函数)传递给 repl 参数。这个可调用函数接受一个参数——匹配对象,returns 是那个匹配的替换,所以它可能是一个简单的包装器,从匹配对象中提取匹配字符串并将其传递给 int_to_Roman :

def int_to_Roman_wrapper(match_obj):
    return int_to_Roman(int(match_obj.group(0)))


sample = 'Carl 5, 15 century' 
new_string = re.sub(r"\d+", int_to_Roman_wrapper, sample)

这给 new_string = 'Carl V, XV century'

这没有 tdelaney 在他们的 中提到的 str.replace 方法的问题:

.replace will replace numbers throughout the string even if they are part of a larger number later on. sample = "Carl 5, 15 century" would fail because the 5 in 15 would be replaced on the first match. The second match would try to replace 15, but its already been destroyed