2011-01-13 34 views
2

Ist eine String-Transformation, die als Regexp-Substitution ausgedrückt wird, eine bequeme Möglichkeit, diese Transformation umzukehren, vorzugsweise in Python?Regexp-Substitution umkehren

Zum Beispiel angesichts der Transformation

def f(x): return re.sub('foo((:?bar)?)', r'\1', x) 

die 'foobar' zu 'bar' und 'foo' auf den leeren String verwandelt, würde Ich mag

def g(x): return re.sub('((:?bar)?)', r'foo\1', x) 

erhalten, die das Gegenteil der Fall ist, in dem Sinne, dass

f(g(x)) == x 

Offensichtlich sind nicht alle Regexp-Substitutionen 1: 1-Zuordnungen, aber mein Wunschdenken ist, dass sie alle umgekehrt werden können, um einen möglichen Eingabewert g(x) zu erhalten, der eine gegebene Ausgabe x von der ursprünglichen Ersetzung ergeben würde.

Warum sollte ich das tun? Ich möchte URLs für beliebige Dateisystempfade generieren, die auf der Analyse von AliasMatch Direktiven in einer Apache-Konfigurationsdatei basieren.

+1

+1 für ein sehr interessantes Problem, aber ich bezweifle, dass es eine nachvollziehbare Lösung gibt, die auch nur entfernt zuverlässig ist. – delnan

Antwort

0

Nun, praktisch, was in diesem Beispiel passiert ist:

xy? -> $1 
y? -> x$1 

Ich bin nicht ganz sicher, was Sie nach dem mit diesem sind - weitere Beispiele würden nicht schaden - aber ich denke, dass die allgemeine Formel sein könnte erweitert, um mehr oder zumindest einfache Fälle abzudecken.

+0

Ja, das ist auch mein Gefühl ... Meine Frage ist, ob ein kleiner Satz von ähnlich einfachen Regeln tatsächlich alle möglichen Regexps abdeckt, und wenn es eine Möglichkeit gibt, solche Regeln anzuwenden, muss ich nicht meinen eigenen Regexp-Parser schreiben . – slowdog

2

Ihr Beispiel funktioniert nicht; ('(bar)?', 'foo$1') ist nicht das Gegenteil von ('foo(bar)?', '$1').

Wenn Sie es versuchen (für den Moment die Gruppe Substitution Abwurf):

import re 
re.sub(r'(bar)?', 'foo', 'xyz') 

Sie fooxfooyfoozfoo bekommen.

Das liegt daran, (bar)? entspricht der Nullzeichenfolge, und die Nullzeichenfolge ist an jeder möglichen Stelle in der Zeichenfolge vorhanden.

Ich würde vorschlagen, dass mit Problemen wie diesem in einem so einfachen Beispiel, möchten Sie möglicherweise eine andere Herangehensweise an was auch immer Sie tatsächlich versuchen zu suchen.

(ließ ich die Gruppe oben, weil das in Python nicht wirklich funktionieren. Wenn Sie re.sub(r'(bar)?', r'foo\1', 'xyz') tun, wird es mit einer Ausnahme fehlschlagen, wenn (bar)? übersprungen wurde. Sie können dieses Problem beheben mit ((bar)?), so nie die äußere Gruppierung Dies ist jedoch nebensächlich für Ihr Problem.)

+0

Danke für die Hinweise. Ich habe das Beispiel wie vorgeschlagen korrigiert. Wenn ich nun "foooxfooyfoozfoo" in die ursprüngliche Ersetzung übergebe, bekomme ich "xyz" zurück. Daher denke ich, dass "fooxfooyfoozfoo" ein akzeptables Ergebnis ist ... – slowdog