我正在尝试通过可选地应用替换来生成字符串变体。
例如,一种替换方案是删除任何空白字符序列。而不是替换所有出现的事件
>>> re.sub(r'\s+', '', 'a b c')
'abc'
– 相反,我需要为每次出现产生两个变体,因为替换是在一个变体中执行的,而不是在另一个变体中执行的。对于'a b c'
我想要变体的字符串
['a b c', 'a bc', 'ab c', 'abc']
IE。所有二元决策的叉积(结果显然包括原始字符串)。
对于这种情况,可以使用re.finditer
and生成变体itertools.product
:
def vary(target, pattern, subst):
occurrences = [m.span() for m in pattern.finditer(target)]
for path in itertools.product((True, False), repeat=len(occurrences)):
variant = ''
anchor = 0
for (start, end), apply_this in zip(occurrences, path):
if apply_this:
variant += target[anchor:start] + subst
anchor = end
variant += target[anchor:]
yield variant
这将为上述示例生成所需的输出:
>>> list(vary('a b c', re.compile(r'\s+'), ''))
['abc', 'ab c', 'a bc', 'a b c']
但是,此解决方案仅适用于固定字符串替换。来自类似组引用的高级功能re.sub
不能这样完成,如下面的示例,用于在单词内的数字序列后插入空格:
re.sub(r'\B(\d+)\B'), r'\1 ', 'abc123def')
如何扩展或更改该方法以接受 re.sub 的任何有效参数(无需编写解析器来解释组引用)?