3

複数行のSQLステートメントを処理するPython関数を書いています。

例えば

multi_stmt = """
-- delete empty responses
DELETE FROM idlongDVR_responses WHERE new_response_code = '';
DELETE FROM idwideDVR_responses WHERE new_response_code = '';

-- create a current responses table for idlongDVR
DROP TABLE IF EXISTS idlongDVR_respCurr;
CREATE  TABLE idlongDVR_respCurr
    SELECT *, MAX(modifiedat) AS latest  FROM idlongDVR_responses
    GROUP BY sitecode, id, dass, tass, field, value, validation_message
    ORDER BY sitecode, id, dass, tass; """

そこで、ダブルハイフン(コメントの開始)が後になく、セミコロンで終わる場合に改行を識別するための正規表現を作成しました。

sql_line = re.compile(r"""
            \n+         # starting from a new line sequence
            (?!(--|\n)) # if not followed by a comment start "--" or newline 

            (.*?)       # <<<<< WHY ARE THESE CAPTURING BRACKETS NEEDED?

            ;           # ending with a semicolon
                      """, re.DOTALL|re.VERBOSE|re.MULTILINE)

stmts = sql_line.findall(multi_statement)

for stmt in stmts:
    stmt = stmt[1]
    if len(stmt) > 0:
        cursor.execute(stmt)

正常に機能しますが、用語を角かっこで囲んでいる場合に限り、 。.*?になり(.*?)ます。私が一致しない場合、私は何も一致しません。

どうしてこれなの?前もって感謝します。

4

2 に答える 2

2

否定先読み内でキャプチャブラケットを使用したため、「これらのキャプチャブラケットが必要です」。

(?!(--|\n))
   ^     ^

これは決して一致してはならないため、一致が成功した場合、最初のキャプチャ グループは常に空になります。のようないくつかのメソッド.findallはキャプチャ グループ (存在する場合) のみを返すため、空の文字列のリストのみが表示されます。

(...)ここを削除すると、正規表現が期待どおりに動作するはずです。[^;]* ところで、代わりに使用できます.*?

sql_line = re.compile(r"\n+(?!--|\n)[^;]*;")
于 2012-08-12T20:27:37.620 に答える
0

使ってるんですfindallよね? findall変だ。正規表現にキャプチャグループがある場合は、キャプチャグループのコンテンツのみが返されます。@KennyTMが指摘したように、先読みの中にキャプチャグループがあり、それはの先読みであるため、グループが何もキャプチャできなかった場合にのみ、全体的な一致が成功します。したがって、空の文字列のリスト。

の周りの角かっこを使用すると、なぜこれらの空のグループが表示されない.*?のか、わざわざ質問しないでください。ドキュメントを読むと、2つのグループで構成されるタプルのリストが返されると思います。1つは空で、もう1つは期待していた一致です。しかし、私は空でないグループしか取得しません。findallそれは私が前に遭遇したことのない無意味のもう一つの層のようです。

ちなみに、MULTILINE旗は必要ありません。アンカーの動作を変更するだけで、文字列全体の最初と最後だけでなく、行の境界でもアンカーを一致させることができます^$すでにご存知かもしれませんが、「マルチラインの場合は使用する必要があります」という非常に永続的な不正なミームが浮かんでいるので、MULTILINE見るたびにスタンプを押します。

于 2012-08-12T21:03:00.483 に答える