我有一个字符串:
"A XYZ B XYZ C"
Run Code Online (Sandbox Code Playgroud)
和索引元组列表:
((2, 5), (8, 11))
Run Code Online (Sandbox Code Playgroud)
我想应用索引定义的每个子字符串替换它们的总和:
A 7 B 19 C
Run Code Online (Sandbox Code Playgroud)
我无法使用字符串替换,因为它将匹配XYZ的两个实例.随着索引在整个过程中转移,使用索引信息替换将在第二次和第四次迭代时中断.
这个问题有一个很好的解决方案吗?
UPDATE.例如,给出了字符串.我不是先验地知道它的内容,也不能在解决方案中使用它们.
我的脏解决方案是:
text = "A XYZ B XYZ C"
replace_list = ((2, 5), (8, 11))
offset = 0
for rpl in replace_list:
l = rpl[0] + offset
r = rpl[1] + offset
replacement = str(r + l)
text = text[0:l] + replacement + text[r:]
offset += len(replacement) - (r - l)
Run Code Online (Sandbox Code Playgroud)
这取决于索引元组的升序顺序.可以做得更好吗?
势在必行和有状态:
s = 'A XYZ B XYZ C'
indices = ((2, 5), (8, 11))
res = []
i = 0
for start, end in indices:
res.append(s[i:start] + str(start + end))
i = end
res.append(s[end:])
print(''.join(res))
Run Code Online (Sandbox Code Playgroud)
结果:
A 7 B 19 C
Run Code Online (Sandbox Code Playgroud)
你可以使用re.sub():
In [17]: s = "A XYZ B XYZ C"
In [18]: ind = ((2, 5), (8, 11))
In [19]: inds = map(sum, ind)
In [20]: re.sub(r'XYZ', lambda _: str(next(inds)), s)
Out[20]: 'A 7 B 19 C'
Run Code Online (Sandbox Code Playgroud)
但请注意,如果匹配数大于索引对,则会引发StopIteration错误.在这种情况下,您可以将默认参数传递给next()要替换子字符串.
如果你想使用索引元组来查找子字符串,这是另一种解决方案:
In [81]: flat_ind = tuple(i for sub in ind for i in sub)
# Create all the pairs with respect to your intended indices.
In [82]: inds = [(0, ind[0][0]), *zip(flat_ind, flat_ind[1:]), (ind[-1][-1], len(s))]
# replace the respective slice of the string with sum of indices of they exist in intended pairs, otherwise just the sub-string itself.
In [85]: ''.join([str(i+j) if (i, j) in ind else s[i:j] for i, j in inds])
Out[85]: 'A 7 B 19 C'
Run Code Online (Sandbox Code Playgroud)
这是一个使用字符串格式化和元组解包的快速但有点脏的解决方案:
s = 'A XYZ B XYZ C'
reps = ((2, 5), (8, 11))
totals = (sum(r) for r in reps)
print s.replace('XYZ','{}').format(*totals)
Run Code Online (Sandbox Code Playgroud)
这打印:
A 7 B 19 C
Run Code Online (Sandbox Code Playgroud)
首先,我们使用生成器表达式来查找每个替换的总数。然后,通过替换'XYZ'为'{}',我们可以使用字符串格式-*totals将确保我们以正确的顺序获得总计。
我没有意识到索引实际上是字符串索引 - 我的错。为此,我们可以使用re.sub如下方法:
import re
s = 'A XYZ B XYZ C'
reps = ((2, 5), (8, 11))
for a, b in reps:
s = s[:a] + '~'*(b-a) + s[b:]
totals = (sum(r) for r in reps)
print re.sub(r'(~+)', r'{}', s).format(*totals)
Run Code Online (Sandbox Code Playgroud)
假设您的字符串中没有~使用波浪号 ( ) - 如果有,请替换为其他字符。这还假设没有一个“替换”组是连续的。
| 归档时间: |
|
| 查看次数: |
1038 次 |
| 最近记录: |