替换正则表达式匹配项的随机子集


re.sub(pattern, replacement, text)

re.sub替换给定字符串text中的每个匹配,除非传递count参数,否则它将替换第一个count匹配配的随机子集(count就是子集大小(

有没有直接的方法来实现这一点?我想到的唯一解决方案是使用re.finditer,获取所有匹配对象……随机地对它们进行子集设置,然后在匹配对象的帮助下手动替换(尽管我不太清楚实现最后一步的好方法(,比如。。。

pattern = "ab"
text = "ab ab ab"
replacement = "ba"
count = 2
match_objects = random.sample(list(re.finditer(pattern, text)), count)
...

我会这样做:

import re, random
def randsub(pat, repl, text, n):
matches = random.sample(list(re.finditer(pat, text)), n)
for i in sorted(matches, key=lambda i: -i.start()):
text = text[:i.start()] + repl + text[i.end():]
return text
for i in range(10):
print(randsub("a{2,3}", "b", "aa|aaa|aa", 2))
b|b|aa
aa|b|b
b|b|aa
b|aaa|b
aa|b|b
b|aaa|b
b|b|aa
b|b|aa
aa|b|b
b|b|aa

所以,你首先得到匹配的列表(就像你在问题中所做的那样(。然而,你不能只按顺序替换所有这些,因为一旦替换了其中一个,其他索引就会关闭。因此,我们在字符串中从最后到第一对它们进行排序。

也许可以计算匹配项,然后选择要替换的项,然后使用re.sub

matches = len(re.findall(pattern, text))
pick = [1] * count + [0] * (matches - count)
random.shuffle(pick)
text = re.sub(pattern, lambda m: replacement if pick.pop() else m.group(0), text)

最新更新