Sto provando a produrre varianti di stringa applicando le sostituzioni facoltativamente.Prodotto combinatorio delle sostituzioni regex
Ad esempio, uno schema di sostituzione sta rimuovendo qualsiasi sequenza di caratteri vuoti. Anziché sostituendo tutte le occorrenze come
>>> re.sub(r'\s+', '', 'a b c')
'abc'
- ho bisogno, invece, due varianti da elaborare per ciascuna volta, dal fatto che la sostituzione viene effettuata in una variante, ma non nell'altro. Per la stringa 'a b c'
voglio avere le varianti
['a b c', 'a bc', 'ab c', 'abc']
es. il prodotto incrociato di tutte le decisioni binarie (il risultato include ovviamente la stringa originale).
Per questo caso, le varianti possono essere prodotti usando re.finditer
e 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
Questo produce l'uscita desiderata per l'esempio precedente:
>>> list(vary('a b c', re.compile(r'\s+'), ''))
['abc', 'ab c', 'a bc', 'a b c']
Tuttavia, questa soluzione funziona solo per fissa -string sostituzioni. Funzioni avanzate da re.sub
come riferimenti di gruppo non può essere fatto in quel modo, come nel seguente esempio per l'inserimento di uno spazio dopo una sequenza di cifre all'interno di una parola:
re.sub(r'\B(\d+)\B'), r'\1 ', 'abc123def')
Come può l'approccio essere esteso o modificato accettare qualsiasi argomento valido su re.sub (senza scrivere un parser per interpretare i riferimenti di gruppo)?
Grazie, questo è un suggerimento molto buono! Le limitazioni per un argomento callable possono essere eliminate facilmente facendone il caso generale: nel ciclo interno, sostituire '... + match.expand (subst)' con '... + subst (match)'. Se l'argomento non è un callable per cominciare, basta avvolgere una funzione (all'inizio del codice): 'se non callable (subst): static_subst = subst; subst = lambda m: m.expand (static_subst) ' – lenz