2012-04-19 60 views
3

希望有人能幫助我解決這個問題!Java正則表達式,用於從字符串中刪除SQL註釋

我有一個SQL文件看起來像這樣:

CREATE TABLE IF NOT EXISTS users(
    id INT UNSIGNED NOT NULL AUTO_INCREMENT, 
    firstname VARCHAR(30) NOT NULL, 
    lastname VARCHAR(30) NOT NULL, 

    PRIMARY KEY (id), 
    CONSTRAINT UNIQUE (firstname,lastname) 
) 
ENGINE=InnoDB 
; 

INSERT IGNORE INTO users (firstname,lastname) VALUES ('x','y'); 
/* 
INSERT IGNORE INTO users (firstname,lastname) VALUES ('a','b'); 
*/ 

我已經BUIT在啓動時使用此函數初始化一個MySQL數據庫的Web應用程序:

public static void initDatabase(ConnectionPool pool, File sqlFile){ 
    Connection con = null; 
    Statement st = null; 
    String mySb=null; 
    try{ 
     con = pool.getConnection(); 
     mySb=IOUtils.copyToString(sqlFile); 

     // We use ";" as a delimiter for each request then we are sure to have well formed statements 
     String[] inst = mySb.split(";"); 

     st = con.createStatement(); 

     for(int i = 0; i<inst.length; i++){ 
      // we ensure that there is no spaces before or after the request string 
      // in order not to execute empty statements 
      if(!inst[i].trim().isEmpty()){ 
       st.executeUpdate(inst[i]); 
      } 
     } 
     st.close(); 
    }catch(IOException e){ 
     throw new RuntimeException(e); 
    }catch(SQLException e){ 
     throw new RuntimeException(e); 
    }finally{ 
     SQLUtils.safeClose(st); 
     pool.close(con); 
    } 
} 

(此功能被發現作者,請原諒我不引用你的名字,我失去了它!)

只要沒有SQL註釋塊,它就可以完美工作。

copyToString()函數基本上做它所說的。 我現在想要的是構建一個正則表達式,它將從字符串中刪除塊註釋。我只在文件中有塊註釋/* */,沒有--

我迄今爲止嘗試:

mySb = mySb.replaceAll("/\\*.*\\*/", ""); 

不幸的是,我不是在正則表達式的很好...

我得到的「匹配的字符串看起來像/* comment */ real statement /* another comment*/」所有的煩惱等等...

+0

你需要在你的正則表達式中使用惰性運算符'?' – Gabber 2012-04-19 10:37:37

回答

7

嘗試

mySb = mySb.replaceAll("/\\*.*?\\*/", ""); 

(注意?,它代表「lazy」)。

編輯:爲了彌補多行註釋,使用這種方法:

Pattern commentPattern = Pattern.compile("/\\*.*?\\*/", Pattern.DOTALL); 
mySb = commentPattern.matcher(mySb).replaceAll(""); 

希望這對你的作品。

+0

它似乎適用於塊註釋在一行上,但不適用於在多行上的塊! '。*?'是否也匹配回車符? – 2012-04-19 11:28:32

+0

Ouch,你需要使用'Pattern.DOTALL'標誌來使用一個完整的'Pattern'實例。我會盡快修改答案。 – 2012-04-19 11:33:18

+0

在閱讀了'Pattern'類的文檔之後,它很有用,非常感謝! – 2012-04-19 11:41:25

2

你需要使用一個不情願的限定詞是這樣的:

public class Main { 

    public static void main(String[] args) { 
     String s = "The matched string look something like /* comment */ real statement /* another comment*/"; 
     System.err.println(s.replaceAll("/\\*.*?\\*/", "")); 
    } 
} 
2

試試下面的辦法:

String s = "/* comment */ select * from XYZ; /* comment */"; 
System.out.println(s.replaceAll("/\\*.*?\\*/", "")); 

輸出:

select * from XYZ; 

.*?代表使用Laziness Instead of Greediness(即表示.*與最大的字符串匹配可能是默認情況下,即貪婪=>必須使用.*?表達式中的?將其配置爲非貪婪)。

+0

感謝您對懶惰和貪婪的解釋。我至少學到了一些東西。但請參閱我對亞歷山大帕夫洛夫郵報的評論。 – 2012-04-19 11:32:05

0

將無法​​正常工作100%

的評論可以在SQL和他們需要保持這種情況下,指定一個有效的字符串的一部分...

我只是一個研究解...看起來是複雜

到目前爲止我有:

\G(?:[^']*?|'(?:[^']|'')*?'(?!'))*?\/\*.*?\*\/ 

但它匹配所有的,而我只需匹配評論...,只是發現了一個單行註釋前面時,它可能會失敗...該死的

+0

好的,現在在字符串中的註釋不會再成爲問題,但對於多行註釋之前的單行註釋......我認爲解析器會更容易:'(?:[^'] *? | '(?:[^'] | '')(?! ')?。?*')* \ķ\/\ * \ * \ /' – user2433984 2013-08-15 00:18:31