İsteğe bağlı olarak ikameler uygulayarak dize varyantları üretmeye çalışıyorum. Örneğin, bir ikame şeması herhangi bir boş karakter dizisini kaldırmaktadır. yerineNormal ifadelerin birleşimsel ürünü
>>> re.sub(r'\s+', '', 'a b c')
'abc'
gibi tüm oluşumları değiştirilmesi dışında - I, bunun yerine, iki varyant, her bir oluşum için, üretilecek olan ihtiyaç, bu ikame ancak diğerinde, bir varyasyonda gerçekleştirilir;. dize 'a b c'
için Ben varyantları
['a b c', 'a bc', 'ab c', 'abc']
yani
sahip olmak istiyorum. tüm ikili kararların çapraz ürünü (sonuç açıkça orijinal dizeyi içerir).>>> list(vary('a b c', re.compile(r'\s+'), ''))
['abc', 'ab c', 'a bc', 'a b c']
Ancak, bu çözüm yolu, sabit çalışır: Bu, yukarıda, örneğin, istenen çıktı üretir
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
:
Bu durum için, varyantlar re.finditer
ve itertools.product
kullanılarak üretilebilir -düzen değiştirmeler. grup başvuruları gibi re.sub
den Gelişmiş özellikler içinde bir kelimeyi rakamlar dizisi sonra boşluk eklemek için şu örnekte olduğu gibi böyle yapılamaz: yaklaşım uzatılabilir veya değiştirilebilir nasıl
re.sub(r'\B(\d+)\B'), r'\1 ', 'abc123def')
re.sub için geçerli bir argümanı kabul etmek (grup referanslarını yorumlamak için bir ayrıştırıcı yazmadan)?
Teşekkürler, bu çok iyi bir ipucu! Kaldırabilir bir argüman için sınırlamalar, genel durumu yaparak kolayca bırakılabilir: iç döngüde, ... + match.expand (subst) 'yi' ... + subst (match) 'ile değiştirin. Eğer argüman başlamak için callable değilse, sadece bir fonksiyona (kodun başında) sarın: 'eğer callable değilse (subst): static_subst = subst; subst = lambda m: m.expand (static_subst) – lenz