2

実際には SQL スクリプトである Java String があります。

CREATE OR REPLACE PROCEDURE Proc
   AS
        b NUMBER:=3;
        c VARCHAR2(2000);
    begin
        c := 'BEGIN ' || ' :1 := :1 + :2; ' || 'END;';
   end Proc;

文字列内に現れるものを除いて、スクリプトをセミコロンで分割したいと思います。目的の出力は、以下で説明する 4 つの異なる文字列です。

1- CREATE OR REPLACE PROCEDURE Proc AS b NUMBER:=3
2- c VARCHAR2(2000)
3- begin c := 'BEGIN ' || ' :1 := :1 + :2; ' || 'END;';
4- end Proc

Java Split() メソッドは、上記の文字列もトークンに分割します。セミコロンが引用符で囲まれているため、この文字列をそのまま保持したいと思います。

c := 'BEGIN ' || ' :1 := :1 + :2; ' || 'END;';

Java Split() メソッドの出力

1- c := 'BEGIN ' || ' :1 := :1 + :2
2- ' || 'END
3- '

文字列内にあるものを除いて、セミコロンで文字列を分割できる正規表現を提案してください。

===================== ケース-2 =======================

上記のセクションに回答があり、その作業

これは別のより複雑なケースです

================================================== ====

SQL スクリプトがあり、各 SQL クエリをトークン化したいと考えています。各 SQL クエリは、セミコロン (;) またはスラッシュ (/) で区切られます。

1- セミコロンまたは / 記号が次のような文字列内にある場合、それらをエスケープしたい

...WHERE col1 = 'some ; name/' ..

2-式は、/* である複数行のコメント構文もエスケープする必要があります。

ここに入力があります

/*Query 1*/
SELECT
*
FROM  tab t
WHERE (t.col1 in (1, 3)
            and t.col2 IN (1,5,8,9,10,11,20,21,
                                     22,23,24,/*Reaffirmed*/
                                     25,26,27,28,29,30,
                                     35,/*carnival*/
                                     75,76,77,78,79,
                                     80,81,82, /*Damark accounts*/
                                     84,85,87,88,90))
;
/*Query 2*/    
select * from table
/
/*Query 3*/
select col form tab2
;
/*Query 4*/
select col2 from tab3 /*this is a multi line comment*/
/

望ましい結果

[1]: /*Query 1*/
    SELECT
    *
    FROM  tab t
    WHERE (t.col1 in (1, 3)
                and t.col2 IN (1,5,8,9,10,11,20,21,
                                         22,23,24,/*Reaffirmed*/
                                         25,26,27,28,29,30,
                                         35,/*carnival*/
                                         75,76,77,78,79,
                                         80,81,82, /*Damark accounts*/
                                         84,85,87,88,90))

[2]:/*Query 2*/    
    select * from table

[3]: /*Query 3*/
    select col form tab2

[4]:/*Query 4*/
    select col2 from tab3 /*this is a multi line comment*/

その半分は、以前の投稿 (link a start) で私に提案されたことによって既に達成できますが、コメント構文 (/*) がクエリに導入され、各クエリもスラッシュ (/) で区切られる場合、式動作しません。

4

3 に答える 3

4

正規表現パターン((?:(?:'[^']*')|[^;])*);は、必要なものを提供するはずです。whileループとを使用して、Matcher.find()すべての SQL ステートメントを抽出します。何かのようなもの:

Pattern p = Pattern.compile("((?:(?:'[^']*')|[^;])*);";);
Matcher m = p.matcher(s);
int cnt = 0;
while (m.find()) {
    System.out.println(++cnt + ": " + m.group(1));
}

提供されたサンプル SQL を使用すると、次のように出力されます。

1: CREATE OR REPLACE PROCEDURE Proc
   AS
        b NUMBER:=3
2: 
        c VARCHAR2(2000)
3: 
    begin
        c := 'BEGIN ' || ' :1 := :1 + :2; ' || 'END;'
4: 
   end Proc

終端の を取得したい場合は、 の代わりに;使用します。m.group(0)m.group(1)

正規表現の詳細については、Pattern JavaDocとこの優れたリファレンスを参照してください。パターンの概要は次のとおりです。

(              Start capturing group
  (?:          Start non-capturing group
    (?:        Start non-capturing group
      '        Match the literal character '
      [^']     Match a single character that is not '
      *        Greedily match the previous atom zero or more times
      '        Match the literal character '
    )          End non-capturing group
    |          Match either the previous or the next atom
    [^;]       Match a single character that is not ;
  )            End non-capturing group
  *            Greedily match the previous atom zero or more times
)              End capturing group
;              Match the literal character ;
于 2011-09-15T18:36:12.337 に答える