字符串格式:将“%0 %1 %2”替换为具有 0,1,2 索引的元组

String formatting : Replace "%0 %1 %2" with tuple with 0,1,2 indexes

我是 python 的初学者。我在 python 中发现了一个问题,Given string in format "%0 is a %1 %2" and a tuple ("Ram", "good", "boy")。表示字符串包含 %x,其中应将其替换为索引 x 的相应元组元素。 (编辑后):忘了提,如果给定的元组是("Ram","good"),答案必须是"Ram is a good %2",即剩余的%x应该保持原样

结果必须是"Ram is a good boy"。我是这样做的(下面是代码)。但我开始知道它可以用更有效的方式编写,而不是。线路......你能帮忙吗?提前致谢

format = "%0 is a %1 %2"
args = ("Ram", "good", "boy")
count = 0
for i in range(0, len(format) + 1):
    if format[i] == '%':
        b= '%'
        b = b + format[i + 1]

        format = format.replace(b, args[int(format[i+1])])
        count+= 1

        if count == len(args):
            break

print format

使用内置的字符串格式。

>>> print('%s is a %s %s' % ('Ram','good','boy'))
Ram is a good boy

根据您的编辑,您正在寻找不同的东西。您可以使用 re.findallre.sub 来完成此操作:

>>> import re
>>> formatstring,args = "%0 is a %1 %2",("Ram", "good", "boy")    
>>> for x in re.findall('(%\d+)',formatstring):
    formatstring = re.sub(x,args[int(x[1:])],formatstring)

>>> formatstring
'Ram is a good boy'

我会使用 str.format,你可以简单地解压元组:

args = ("Ram", "good", "boy")


print("{}  is a {} {}".format(*args))
Ram is  a good boy

如果需要先操作原始字符串,请使用re.sub :

import re

"%2 and %1 and %0"
 args = ("one", "two", "three")

print(re.sub(r"%\d+", lambda x: "{"+x.group()[1:]+"}", s).format(*args))

输出:

In [6]: s = "%2 and %1 and %0"

In [7]: re.sub(r"%\d+", lambda x: "{"+x.group()[1:]+"}", s).format(*args)
Out[7]: 'three and two and one'

In [8]: s = "%1 and %0 and %2"

In [9]: re.sub(r"%\d+",lambda x: "{"+x.group()[1:]+"}", s).format(*args)
Out[9]: 'two and one and three'

%\d+ 匹配百分号后跟 1 个或多个数字,lambda 中的 x 是一个匹配对象,我们使用 .group 从中获取匹配的字符串并切片只是 {} 中包含数字字符串的数字用作 str.format.

的占位符

重新评论你可以拥有比 args 更多的占位符,sub 需要一个 count arg 的最大替换数量:

s = "%0 is a %1 %2"
args = ("Ram", "Good")
sub = re.sub(r"%\d+\b", lambda x: "{"+x.group()[1:]+"}", s,count=len(args)).format(*args)

print(sub)

输出:

Ram is a Good %2

要为任意顺序工作,需要更多的逻辑:

s = "%2 is a %1 %0"
args = ("Ram", "Good")

sub = re.sub(r"%\d+\b", lambda x: "{"+x.group()[1:]+"}" if int(x.group()[1:]) < len(args) else x.group(), s).format(*args)

print(sub)

输出:

%2 is a Good Ram

将 lambda 逻辑移到函数中会更好一些:

s = "%2 is a %1 %0"
args = ("Ram", "Good")
def f(x):
    g = x.group()
    return "{"+g[1:]+"}" if int(x.group()[1:]) < len(args) else g

sub = re.sub(r"%\d+\b",f,  s).format(*args)

或者如果占位符总是独立的,则使用拆分和连接:

print(" ".join(["{"+w[1:]+"}" if w[0] == "%" else w for w in s.split(" ")]).format(*args))

three and two and one 

也许可以使用 string.replace 将各种 %xes 替换为对应的元组,例如:

format = "%0 is a %1 %2"
args = ("Ram", "good", "boy")

result = format  # Set it here in case args is the empty tuple

for index, arg in enumerate(args):
    formatter = '%' + str(index)  # "%0", "%1", etc
    result = result.replace(formatter, arg)

print(result)