2016-06-10 13 views
2

Ich schreibe ein schnelles Python-Skript, um einige unserer Hibernate Mapping-Dateien zu überprüfen. Ich versuche, dieses Stück Python zu verwenden, um die Tabellennamen eines POJO zu erhalten, ob sein Klassenpfad vollständig definiert ist:Backslashes in Python Regex

searchObj = re.search(r'<class name="(.*\\.|)' + pojo + '".*table="(.*?)"', contents) 

aber - sagen pojo ‚MyObject‘ ist - die Regex ist nicht passend es zu dieser Zeile:

<class name="com.place.package.MyObject" table="my_cool_object" dynamic-insert="true" dynamic-update="true"> 

Wenn ich die Zeichenfolge gedruckt werden (während in Pdb gestoppt) ich bin auf der Suche, ich sehe dies:

'<class name="(.*\\\\.|)MyObject".*table="(.*?)"' 

ich ziemlich verwirrt bin, was falsch läuft Hier. Zum einen hatte ich den Eindruck, dass das Präfix "r" es so gemacht hat, dass die Backslashes nicht entkommen konnten. Trotzdem, wenn ich eine der Schrägstriche entfernen, so dass mein Suchbegriff dies:

searchObj = re.search(r'<class name="(.*\.|)' + pojo + '".*table="(.*?)"', contents) 

Und die Zeichenfolge gesucht wird

'<class name="(.*\\.|)MyObject".*table="(.*?)"' 

Es ist noch kein Spiel zurück. Was läuft hier falsch? Der Regex-Ausdruck, den ich verwenden möchte, funktioniert auf regex101.com (mit nur einem Backslash im scheinbar problematischen Bereich.) Irgendeine Idee, was hier falsch läuft?

+0

@Keatinge - Warum es nicht ist, dann passend, wenn ich nur einen Backslash? Der Regex sollte basierend auf dieser Site gut sein. Auch wenn es nur MyObject ist, stimmt es überein, aber wenn es com.place.package.MyObject ist, tut es das nicht. –

Antwort

2

Vor diesem Hintergrund:

re.search(r'<class name="(.*\\.|)' + pojo + '".*table="(.*?)"', contents) 

Das ist der erste Teil des Musters wie folgt interpretiert:

1. class name=" a literal string beginning with c and ending with " 
2. (    the beginning of a group 
3. .*    zero or more of any characters 
4. \\    a literal single slash 
5. .     any single character 
6. OR 
7.      nothing 
8.)    end of the group 

Da die Zeichenfolge, die Sie suchen kein Backslash haben, es wird nicht übereinstimmen.

Wenn Sie beabsichtigen, was für \\. ist „eine wörtliche Zeit“ zu bedeuten, müssen Sie einen umgekehrten Schrägstrich, da es sich in einer rohen String ist: \.

Auch die Gruppe endet mit einem Rohr seltsam scheint. Ich bin mir nicht sicher, was du denkst. Wenn Sie sagen wollen "eine beliebige Anzahl von Zeichen, die mit einem Punkt enden, oder nichts", können Sie das mit (.*\.)? tun, da ? "Null oder eine der vorhergehenden Übereinstimmung" bedeutet.

Dies scheint für mich zu arbeiten:

import re 
contents1 = '''<class name="com.place.package.MyObject" table="my_cool_object" dynamic-insert="true" dynamic-update="true">''' 
contents2 = '''<class name="MyObject" table="my_cool_object" dynamic-insert="true" dynamic-update="true">''' 
pojo="MyObject" 

pattern = r'<class name="(.*\.)?' + pojo + '.*table="(.*?)"' 

assert(re.search(pattern, contents1)) 
assert(re.search(pattern, contents2)) 
+0

Ja, es mit einer Pipe beenden und tun, was Sie sagten funktionieren auf die gleiche Weise. Was den Rest Ihres Kommentars anbelangt, so habe ich in der zweiten Hälfte meines Posts gezeigt, dass es sich auch nicht lohnt, nur r '\.' Entweder ist das nicht das Problem, auf das ich stoße. –

+0

@TrevorThackston: der Backslash ist definitiv zumindest ein Teil des Problems. Ich habe meine Antwort mit einem Arbeitsbeispiel aktualisiert, das zeigt, dass das Muster sowohl einem vollständig qualifizierten Namen als auch einem relativen Namen entspricht. –

+0

Sie haben Recht - Ich meine nur, dass ich gesagt habe, dass ich es schon versucht habe. Wie auch immer, ich habe das Problem, das es in meinem realen Datensatz hatte, herausgefunden. Einige der Tabellen haben nach der Tabelle "mutable =" false "", so dass es verwirrend wurde und Fehler aufzeigte. Ich habe herausgefunden, wie ich das beheben kann. –

2

Auf Pythex ich diese Regex versucht:

<class name="(.*)\.MyObject" table="([^"]*)"

auf dieser Zeichenfolge:

<class name="com.place.package.MyObject" table="my_cool_object" dynamic-insert="true" dynamic-update="true">

und bekam diese beiden Spiel fängt:

  1. com.place.package
  2. my_cool_object

Also ich denke, in Ihrem Fall, diese Zeile

searchObj = re.search(r'<class name="(.*)\.' + pojo + '"table="([^"]*)"', contents) 

wird das gewünschte Ergebnis produzieren.


Über die verwirrenden Schrägstriche - Sie fügen zwei und dann zeigen vier nach oben auf der Python-Dokumentation 7.2. re — Regular expression operations es erklärt, dass r'' ist „raw String Notation“, verwendet Python regulären Charakter zu entkommen, zu umgehen, die einen umgekehrten Schrägstrich verwendet. Also:

  • '\\' bedeutet „eine Zeichenfolge aus einem umgekehrten Schrägstrich“, da der erste Schrägstrich in der Zeichenfolge den zweiten Backslash entkommt. Python sieht den ersten Backslash und denkt, 'das nächste Zeichen ist ein besonderes Zeichen'; dann sieht er die zweite und sagt, "das Sonderzeichen ist ein tatsächlicher Backslash". Es wird als einzelnes Zeichen \ gespeichert. Wenn Sie Python bitten, dies auszudrucken, wird es die Ausgabe verlassen und Ihnen "\\" zeigen.
  • r'\\' bedeutet "eine Zeichenfolge bestehend aus zwei tatsächlichen Backslashes.Es wird als Zeichen \ gefolgt von Zeichen \ gespeichert. Wenn Sie Python bitten, dies auszudrucken, wird es die Ausgabe verlassen und Ihnen "\\\\" zeigen.
+0

Das Problem ist mit dem ersten Teil der Regex, nicht der zweite, und Sie haben den ersten Teil so geändert, dass es nur auf qualifizierten Pfadnamen funktioniert. –

+0

@TrevorThackston Ich weiß nicht, was Sie mit "qualifizierten Pfadnamen" meinen, also bitte klarstellen. Gib mir ein paar Beispiele von Dingen, die der erste Teil zusammenbringen soll. –

+0

ich möchte es diese beiden passen: '' und '' –