1

SQLスクリプトからテーブル名を抽出しようとしています。私は次の文字列を持っています:

from db1.tableX tbx1 --quantity table
inner join tableY tbx2  on tbx1.xyz=tbx2.xyz

tableyデータベース名のプレフィックスが付いていないため、この文字列と一致させたくありません。私がこれを行おうとしている方法は、データベース名の前の文字列で「on」という単語を検出することです。

私の正規表現は一致tablexしていますが、一致しているので、式を一致させたくありませtbx1ん。

このような状況でのみ一致させたい。

from db1.tableX tbx1 --quantity table
inner join db1.tableY tbx2 on tbx1.xyz = tbx2.xyz

私の正規表現は私tableXに与えるべきでありtableY、データベース名が接頭辞として付けられているためです。

これが私の表現です:

(insert\s+into|from|inner\s+join|left\s+outer\s+join|join)\s+[\sa-zA-Z0-9_$#-]*\.\s*(?<table>[a-zA-Z0-9_]+)(?=\s+[a-zA-Z0-9_$#-]+)*
4

2 に答える 2

1

ステップバイステップ:

1)http://regexr.com?33tto

試合の最後になぜその先読みをしたのかわかりません。必要ないと思うので削除しました。

2)http://regexr.com?33ttr

今、私たちはあなたが示した問題に到達します。問題は、データベース名の一致[\sa-zA-Z0-9_$#-]*に、有効な文字として空白が含まれていることです。私もそれを削除しました。

3)http://regexr.com?33ttu

これは望ましい結果ですか?

于 2013-02-26T15:31:54.580 に答える
1

あなたはあなたの表現を単純化することができます

(?<=\b(from|join)\s+[a-zA-Z0-9_$#-]*\.\s*)[a-zA-Z0-9_]+

名前付きグループを使用せずに、テーブル名を直接生成します。パターンを使用しています

(?<=prefix)find

これにより、一致値として「find」の部分のみが返されます。プレフィックスとして、「from」または「join」を使用し、その後にデータベース名の後にドットと場合によってはスペースを使用します。

\b単語の始まりまたは終わりです。

最後の部分[a-zA-Z0-9_]+はテーブル名です。

内部結合、外部結合などがあるかどうかは関係ないので、この区別を削除しました。

コメントは、何でも含めることができ、どこにでも表示される可能性があるため、検出するのは醜いです。また、2種類のコメント-- Until end of lineとがあり\* ... *\ます。

このようなコメントやスペースを検出しようとすることができます

(\s|--.*?$|\\\*.*?\*\\)+

バックスペースとスターをエスケープする必要があるため、に\*なり\\\*、に*\なり\*\\ます。

$行末を示します。?after.*は、一度に複数のコメントがスキップされないようにするため、コメント間の意味のあるテキストをスキップします。

これはほとんどの場合に機能します。ただし、コメントのような構造を文字列リテラルに含めることができますSELECT 'hello -- world' AS greeting FROM ...。これはコメントではありません!SQLテキストの完全な構文解析がないと、考えられるすべてのケースをカバーすることはできません。ただし、正規表現ではこれを行うことはできません。正規表現には限界があります。

于 2013-02-26T18:09:59.900 に答える