Ich habe SQL-Codes und möchte den Tabellennamen nach dem Schlüsselwort "insert" extrahieren.Python: Wie finden Sie alle Übereinstimmungen in einem mehrzeiligen String, aber nicht von einem bestimmten Wort weiter?
Grundsätzlich würde ich mit den folgenden Regeln extrahieren mag:
- Enthält das Wort „Einfügen“
- gefolgt von dem Wort „in“, die
- optional ausschließen, wenn das ein Thema " - "(das ist ein einzeiliger Kommentar in SQL) irgendwo vor dem Einfügen in (optional) Schlüsselwort.
- Ausschließen, wenn Einfügen in (optional) Schlüsselwort ist zwischen "/ *" und "* /" (was mehrzeiliger Kommentar in SQL ist).
- Holen Sie sich das nächste Wort (table_name) nach Einsatz in (optional) Stichwort
Beispiel:
import re
lines = """begin insert into table_1 end
begin insert table_2 end
select 1 --This is will not insert into table_3
begin insert into
table_4
end
/* this is a comment
insert into table_5
*/
insert into table_6
"""
p = re.compile(r'^((?!--).)*\binsert\b\s+(?:into\s*)?.*', flags=re.IGNORECASE | re.MULTILINE)
for m in re.finditer(p, lines):
line = lines[m.start(): m.end()].strip()
starts_with_insert = re.findall('insert.*', line, flags=re.IGNORECASE|re.MULTILINE|re.DOTALL)
print re.compile('insert\s+(?:into\s+)?', flags=re.IGNORECASE|re.MULTILINE|re.DOTALL).split(' '.join(starts_with_insert))[1].split()[0]
Tatsächliches Ergebnis:
table_1
table_2
table_4
table_5
table_6
Erwartetes Ergebnis: table_5 nicht zurückgegeben werden soll da ist es zwischen/* und */
table_1
table_2
table_4
table_6
Gibt es eine elegante Möglichkeit, dies zu tun?
Vielen Dank im Voraus.
EDIT: Danke für Ihre Lösungen. Ist es möglich, reine Regex ohne Stripping-Zeilen aus dem Originaltext zu verwenden?
Ich möchte die Zeilennummer anzeigen, wo Tabellenname aus der ursprünglichen Zeichenfolge gefunden werden kann.
Aktualisiert Code unten:
import re
lines = """begin insert into table_1 end
begin insert table_2 end
select 1 --This is will not insert into table_3
begin insert into
table_4
end
/* this is a comment
insert into table_5
*/
insert into table_6
"""
p = re.compile(r'^((?!--).)*\binsert\b\s+(?:into\s*)?.*', flags=re.IGNORECASE | re.MULTILINE)
for m in re.finditer(p, lines):
line = lines[m.start(): m.end()].strip()
line_no = str(lines.count("\n", 0, m.end()) + 1).zfill(6)
table_names = re.findall(r'(?:\binsert\s*(?:into\s*)?)(\S+)', line, flags=re.IGNORECASE|re.MULTILINE|re.DOTALL)
print '[line number: ' + line_no + '] ' + '; '.join(table_names)
Versuchte Look-Ahead/Lookbehind mit denen zwischen/* auszuschließen und * /, aber es ist nicht mein erwartetes Ergebnis.
Ich würde Ihre Hilfe zu schätzen wissen. Vielen Dank!
vergessen Sie, dass beide '--' und'/* 'wird wahrscheinlich keine Kommentare starten, wenn es inside ist e eine Zeichenfolge ... –
Ich denke, Sie sollten über 'Lookbehind Behauptung 'wissen –