python 如何在字符串中所选字符后添加出现次数?

xt0899hw  于 2023-04-10  发布在  Python
关注(0)|答案(3)|浏览(119)

我有一个包含多个Q =的字符串,目标是在每个Q之后添加出现的次数。
例如,'Q = 1 t h \n Q = 2 t h \n Q = 3 t h'应为'Q1 = 1 t h \n Q2 = 2 t h \n Q3 = 3 t h'
下面是我的方法:

import re

test = 'Q = 1 t h \n Q = 2 t h \n Q = 3 t h'
num = test.count('Q =')
pattern = re.compile('[Q]')

for n in range(num):
    where = [m for m in pattern.finditer(test)]
    test = test[:where[n].start()+1]+f'{n+1}'+test[where[n].start()+1:]

print(test)

有没有更好的解决办法?

hc2pp10m

hc2pp10m1#

可能的办法:
1.使用正则表达式的.sub方法来替换每个匹配的字符串。(我想包括一个参考链接,但我找不到一个合适的问题,直接询问使用正则表达式进行替换 *,其中OP还不知道re.sub *。)它接受匹配的字符串并返回替换字符串can accept a function
我们需要的函数实际上并不需要匹配的字符串作为其逻辑(因为它是一个常数,而且因为将其拆开比重新创建我们需要的部分更难),但是每次都需要给予不同的结果。我们可以用逻辑来创建这些结果,只需从itertools.count中提取interpolates数字(which produces an unlimited sequence of integers counting up, on demand)。由于该函数只需要一次性使用该迭代器,因此我们可以在本地声明它,并且(carefully)将其用作lambda中的闭包。

import re
from itertools import count
from functools import partial

pattern = re.compile('Q =')
test = 'Q = 1 t h \n Q = 2 t h \n Q = 3 t h'
c = count(1)
test = pattern.sub(lambda _: f'Q{next(c)} =', test)

1.由于搜索到的子字符串是一个常量,所以不用正则表达式,只需.split() the string on that value,生成并collect替换字符串interweave the replacements with the parts in betweenjoin the results again

from itertools import count

test = 'Q = 1 t h \n Q = 2 t h \n Q = 3 t h'

between = test.split('Q =')
parts = [None] * (len(between) * 2 - 1)
parts[::2] = between
parts[1::2] = [f'Q{i} =' for i in range(1, len(between))]
test = ''.join(parts)

1.假设我们可以假设字符串 * 也 * 分成行(即,在每个“问题”部分的末尾有\n):将字符串拆分为这些行,使用类似的技术 * 替换 * 每行的开头,然后将这些行重新连接在一起:

test = 'Q = 1 t h \n Q = 2 t h \n Q = 3 t h'
lines = test.split('\n')
test = '\n'.join(
    line.replace('Q =', f'Q{i} =') for i, line in enumerate(lines, 1)
)

在这里,enumerate是一个内置函数,它取代了count逻辑-它自动匹配来自itertools.count的值,以及来自另一个序列的值(在这里,原始文本的lines)。
1.如果我们不能做出这样的假设,那么使用正则表达式来分割字符串。使用lookahead assertion,这样实际匹配的模式不包含任何文本,但是在每个Q =之前匹配,允许字符串在这些地方被分割。然后像以前一样进行替换。这一次,我们使用一个空字符串连接,因为我们没有从原始数据中删除换行符。

import re

pattern = re.compile('(?=Q =)')
test = 'Q = 1 t h \n Q = 2 t h \n Q = 3 t h'
lines = pattern.split(test)
test = ''.join(
    line.replace('Q =', f'Q{i} =') for i, line in enumerate(lines)
)

请注意,这次我们从0开始枚举,因为以这种方式拆分将在lines的开头产生一个空字符串。

jdg4fx2g

jdg4fx2g2#

我会这样使用 regex 方法:

out = re.sub(r"Q\s*=\s*(\d+)", r"Q\1 = \1", test)

或者简单地使用replace(* 按照您的方法 *):

out = "\n".join([l.replace("Q =", f"Q{i+1} =") for i, l in enumerate(test.split("\n"))])

输出:

>>> print(out)

'Q1 = 1 t h \n Q2 = 2 t h \n Q3 = 3 t h'
ktca8awb

ktca8awb3#

如果你的字符串不包含花括号,你可以使用format函数注入序列号:

test = "Q = 1 t h \n Q = 2 t h \n Q = 3 t h"

result = test.replace("Q =","Q{} =").format(*range(1,test.count("Q =")+1))

print(result)

Q1 = 1 t h 
 Q2 = 2 t h 
 Q3 = 3 t h

如果可以有花括号,你可以使用split代替,使用“Q =”作为分隔符分隔字符串,并使用注入的编号重新组合它:

result = "".join(f"Q{i} ="*(i>0)+s for i,s in enumerate(test.split("Q =")))

或者你可以使用一个循环来一次替换一个“Q =”:

for i in range(test.count("Q =")):
    test = test.replace("Q =",f"Q{i+1} =",1)

print(test)
    Q1 = 1 t h 
     Q2 = 2 t h 
     Q3 = 3 t h

相关问题