2016-06-20 15 views
1

Ich versuche gerade, eine Datei nach einem bestimmten Muster zu durchsuchen und Teile des übereinstimmenden Musters zu erfassen, die in einer Ersatzzeichenfolge verwendet werden sollen.Python 3 REGEX-Hilfe

Mein aktuelles Python 3-Skript verwendet dieses Muster und erfasst die Daten in einfachen Fällen.

def readFile(filename): 
     pattern = re.compile(b"(<%InsertIf expression=\"\$\{\(\((.*?)\[\'(.*?)\'\].*?\'(.*?)\'\)\)\}\".*?\/InsertIf%>)", re.DOTALL) 
     with open(filename, 'r+') as f: 
      data = mmap.mmap(f.fileno(), 0) 
      for match in re.finditer(pattern, data): 
       print(match.groups()) 
       print ("") 

Wenn beispielsweise diese Schnipsel der Datei übereinstimmt, gefunden

<%InsertIf expression="${((user.MemberAttribute['treatmentcode'] == 'NM'))}" %>some random text goes here<sup>®</sup> membership<%/InsertIf%><%InsertIf expression="${((user.MemberAttribute['treatmentcode'] == 'N1'))}" %>some random text goes here<sup>®</sup> upgrade.<%/InsertIf%><br /> 

I erhalten, die gewünschte Ausgabe von dem regulären Ausdruck I für diese Muster an der richtigen Stelle:

(b'<%InsertIf expression="${((user.MemberAttribute[\'treatmentcode\'] == \'NM\'))}" %>some random text goes here<sup>\xc2\xae</sup> membership<%/InsertIf%>', b'user.MemberAttribute', b'treatmentcode', b'NM') 

(b'<%InsertIf expression="${((user.MemberAttribute[\'treatmentcode\'] == \'N1\'))}" %>some random text goes here<sup>\xc2\xae</sup> upgrade.<%/InsertIf%>', b'user.MemberAttribute', b'treatmentcode', b'N1') 

Jedoch Wenn der InsertIf-Ausdruck zusätzliche Bedingungen hat, kann ich das passende Muster für die Regex nicht herausfinden.

Hier sind zwei komplexe Snippets, die ich versuche zu lösen. In einem Fall gibt es ein zusätzliches '||' bedingt. In der anderen gibt es ein "und" bedingt.

<%InsertIf expression="${((user.MemberAttribute['country'] == 'US') || (user.MemberAttribute['country'] == 'CA'))}" %> 

Im obigen Fall ich einen zweiten Satz von Aufnahmen erwarten:

  1. Voll InsertIf erfasst String
  2. user.MemberAttribute
  3. Land
  4. US
  5. user.MemberAttribute
  6. Land
  7. CA

Aber da das Muster für die bedingte die 4. Erfassung kehrt nicht berücksichtigt: 4. US ') || (User.MemberAttribute [ 'Land'] == ‚CA

UND Beispiel

<%InsertIf expression="${((user.MemberAttribute['country']=='US') and (user.MemberAttribute['treatmentcode']=='NM'))}" %><%InsertCSE id="XXXXX"%><%/InsertIf%> 

ähnliche Erwartungen und schlechtes Ergebnis als 'Beispiel ||' oben.

Jede mögliche Unterstützung mit dem Muster sehr geschätzt. ich immer noch reguläre Ausdrücke lerne und dies ist nur ein bisschen aus meiner Tiefe.

Dank.

zusätzliche Details wie requ Hinzufügen ested: Ich versuche im Wesentlichen eine Umwandlung einer Syntax in eine andere innerhalb einer Datei durchzuführen.

Beispiel: Ich möchte dieses Muster finden ...

<%InsertIf 
expression="${((user.MemberAttribute['treatmentcode']=='NM'))}" %> 
<%InsertCSE id="4000116068"%><%/InsertIf%> 
<%InsertElse expression="${((user.MemberAttribute['treatmentcode']=='N1'))}" %> 
<%InsertCSE id="4000116069"%> 
<%/InsertElse%> 

und wandeln es in diesem Muster, während die variablen Werte zu bewahren:

%%[ if treatmentcode == "NM" then ]%% 
%%=contentArea("4000116068")=%% 
%%[ elseif treatmentcode == "N1" then ]%% 
%%=contentArea("4000116069")=%% 
%%[ endif ]%% 

Die Herausforderung kommt ins Spiel, wenn es zusätzliche conditionals als Teil des Ausdrucks selbst. Die obigen Original-Snippets zeigen mehr Details für die Eingabe. Ich kann einfache Ausdrücke wie gewünscht arbeiten, aber es fällt auf die komplexeren Aussagen.

Ich habe zunächst versucht, eine einfache InsertIf-Fall zu nehmen und es funktioniert. Ich könnte dann die Datei loopen, um den InsertElse und andere Fälle zu behandeln.

+0

möglich zu sein Dies scheint nicht zu bekommen. Am nächsten kam es, dass das letzte Vorkommen des Musters immer übereinstimmte (ich probierte nur das '||' Sample). '(<% InsertIf Ausdruck =" \ $ {\ ((?: \ ((*? \ * *?) \ '' (. *?) '\] ==' (. *?) '\) (?: \ | \ |)?) + \)} "\ s?%>. *? <% \/InsertIf%>)". Dies kann Ihnen helfen zu verstehen, warum, wie das gleiche gilt für Python wie für JavaScript: http://StackOverflow.com/A/3537914/1476989 –

+0

Sie können testen, die Regex ich hier gemacht: http://regexr.com/3dljk –

+0

Sie erhalten nur so viele Gruppenwerte, wie es Gruppen in Ihrer Regex gibt, wenn Sie keine 7 Gruppen definieren, können Sie nicht mehr erhalten. Was ist, wenn Sie 7 '||' Bedingungen haben? Kannst du PyPi 'regex' Modul benutzen? Dort können Sie die '.captures'-Sammlung verwenden. –

Antwort

0

Geben Sie ein idear, um das erste Problem zu lösen. Sie können zwei Schritte:

  1. den gesamten Ausdruck mit Muster erhalten:

    re.compile(b"(<%InsertIf expression=\"\$\{\(\((.*?)\)\)\}\".*?\/InsertIf%>)", re.DOTALL)

  2. Wenn Sie den Kontext erhalten, können Sie ein anderes Muster verwenden können, um Namen, Attribut und Wert zu finden

    ([^\[]*)\[\'([^\']*)\'\].*?\'([^\']*)\'

    hier, würde Ich mag die Verwendung [\']* oder [\[]* statt .*?

findall() mit allen Übereinstimmungen zu finden.

Das zweite Problem, das eine „Sprache“ auf einem anderen Bedürfnisse konvertiert mehr Information wie ==