2016-10-26 17 views
1

私のクエリを分割したいが、私の要求に正確に合った答えを得られなかった。Java:セミコロンで区切られた文字列を分割するが、エスケープ+セミコロンを引用符で囲まずに

私は私の文字列以下のように持っている:1を選択し

; \\ 2を選択します。 3 \\を選択; 'S3:// mybucket/mydataという' から顧客をコピー '; aws_secret_access_key = secret_keyに\\; master_symmetric_key = master_keyにaws_access_key_id = ACCESS_KEY \\'

所望の出力資格情報:

は\\ 2

から3 \\

コピー顧客を選択選択選択 'S3:// mybucket/mydataという' 資格証明書「aws_a ccess_key_id = ACCESS_KEY \\; aws_secret_access_key = secret_keyに\\; master_symmetric_key = master_keyに」

私はエスケーについての解決策を見つけました。しかしそれは私の要求に合っていません。

(?<!\);引用符で+セミコロンをエスケープ無視する方法

Handling delimiter with escape characters in Java String.split() method

私を助けてください。

+0

また、「コピー顧客」の前には「\\;」があります。それと 'access_key \\;'には違いはありません。あなたが何を使っていても、コンピュータはこれら2つの '\\;'を区別できません。 – RealSkeptic

答えて

0

私は別の解決策を試しました。今回は正規表現がありません。私は思ったほど多くの賢い弦でこれをチェックしました。期待通りに機能しました(今度も期待通りにうまくいくでしょう)。これをチェックしてください。

 String s ="select 1;r;select \\2; select 3\\;copy customer from 's3://mybucket/mydata' credentials 'aws_access_key_id=<access-key-id>\\;aws_secret_access_key=<secret-access-key>\\;master_symmetric_ke‌​y=<master-key>'"; 
       //"select 1;r;select \\2; select 3\\;copy customer from 'r;s3://mybucket/mydata;r' credentials 'a_key;b_key;c_key\\;r' 'aws_access_key_id=access_key\\;aws_secret_access_key=secret_key\\;master_symmetric_key=master_key'"; 
     s = s.replace("\\","\\\\"); 
     List<String> tokens = new ArrayList<String>();    
     int i = 0;  
     int j = 0; 
     String backup = s; 
     while (i < s.length()){ 
     char c = s.charAt(i);  
      if(c==';'){ 
      String previous = s.substring(0,i); 
      int quotesBefore = StringUtils.countMatches(backup.substring(0,j), "'"); 
      if(i<2 || quotesBefore==0 || (i>1 && (quotesBefore & 1) == 0 || ((quotesBefore & 1) != 0) && !(s.charAt(i-1)=='\\' && s.charAt(i-2)=='\\'))){//Even quotes before OR (odd quotes AND not \\ right before)     
       tokens.add(previous); 
       if(i>0)s=s.substring(i+1); 
       i=0; 
      } 
      } 
      i++;j++; 
     } 
     tokens.add(s); 
     for(String t : tokens) { 
      System.out.println("> "+t); 
     } 

基本手順:

  1. Itterate文字列の文字

  2. それぞれ1つのチェックのために、それはそれが本当ならば、その前の文字を取得し、セミコロン

  3. だ場合、カウントこれらの文字を奇数であるか、またはeである場合にのみ、それらの文字をリストに追加してくださいven 数字ですが、セミコロンは「\\」でエスケープされません
+0

ありがとうございました!しかし、 '' s3:// mybucket/mydataの資格情報 'aws_access_key_id = <アクセスキーID> \\; aws_secret_access_key = <シークレットアクセスキー> \\; master_symmetric_key = 'から顧客をコピーしてください;ワーキング。 T.T –

+0

これを修正しました!見てみな。 –

+1

ありがとう!それはうまくいきます。 –

1

私はそれがsollutionだと思う:

String line = "select 1;select \\2; select 3\\;copy customer from 's3://mybucket/mydata' credentials 'aws_access_key_id=access_key\\;aws_secret_access_key=secret_key\\;master_symmetric_key=master_key'"; 
line = line.replace("\\","\\\\");//To avoid missing \ 
String[] tokens = line.split(";(?=([^']*'[^']*')*[^']*$)");//To split on semmicolons, but not those inside quotes 
for(String t : tokens) { 
    System.out.println("> "+t); 
} 

はあなたがここにhttp://rextester.com/MLTA75734

+0

ありがとうございました。しかし、引用符で囲まれたセミコロンだけであれば、私はそれを無視したくありません。 (\ n)c_key(\ n):平均分割 –

0

それをテストすることができますすることができ、ユーザの外部の.jar 、コモンズ・ラング-2.6.jarのような

String str = "select 1;select \\2; select 3\\;copy customer from 's3://mybucket/mydata' credentials 'aws_access_key_id=access_key\\;" 
      + "aws_secret_access_key=secret_key\\;" 
      + "master_symmetric_key=master_key'"; 
    str = StringEscapeUtils.escapeJavaScript(str); // method from external jar 
    String st[] = str.split(";"); 
    for(int i=0;i<st.length;i++) 
    System.out.println(st[i]); 

あなたのお役に立てば幸いです。

関連する問題