publicstatic String removeCommentInSql(String sql1){ // match two patterns, one is "-- comment", the other is "/* comment */" final String[] commentPatterns = new String[]{"--(?!.*\\*/).*?[\r\n]", "/\\*(.|\r|\n)*?\\*/"}; for (int i = 0; i < commentPatterns.length; i++) { sql1 = sql1.replaceAll(commentPatterns[i], ""); } sql1 = sql1.trim(); return sql1; }
这个方法没有考虑到SQL中字符串,比如`、"、',可能也包含注释格式的字符串。比如说:
1 2 3
select*from a where price='2012--12-14', select*from a where price=\"/* this is not comment */\" SELECT*from a WHERE `--test` is not null
/** * SqlCommentParser is used to parse the comment position in sql * * SqlCommentParser thinks that a sql string is made up of three types of strings. * One is the quote type, the other is the comment type, and the other is the ID type * * E.g: * select * from a where column_b='this is not comment'-- this is comment * in this sql, * the quote type of strings is 【'this is not comment'】 * the comment type of strings is 【-- this is comment】 * the ID type of strings is 【select * from a where column_b=】 * * the quote type is consist a pair of '、"、`, and the quote internal string can be any string * the comment type is consist of --、/* * the ID type is a strings that do not meet the above two types * * note: * (1)SqlCommentParser cannot identify whether the string conforms to the SQL specification, * (2)If you want quote、comment to support more, you should add more case in the method of nextComment * */ publicclassSqlCommentParser{
public String removeCommentSql(){ StringBuilder newSQL = new StringBuilder(); int startIndex = 0; while (true) { Comment comment = this.nextComment(); // the sql is parse over if (comment == null) { // process the sql without comment case if (startIndex != sql.length()) { newSQL.append(sql, startIndex, sql.length()); } break; } else { newSQL.append(sql, startIndex, comment.startIndex); startIndex = comment.endIndex; } } return newSQL.toString();
}
/** * Get next comment of sql * * it only support two comment modes, one is -- ,the other is /* * @return null, only if sql parser over; */ public Comment nextComment(){ while (pos < sql.length()) { char c = sql.charAt(pos); Integer startIndex = null; switch (c) { // ignore the type of quote case'\'': start = pos; ++pos; while (pos < sql.length()) { c = sql.charAt(pos); ++pos; if (c == '\'') { break; } } break;
case'`': start = pos; ++pos; while (pos < sql.length()) { c = sql.charAt(pos); ++pos; if (c == '`') { break; } } break;
case'\"': start = pos; ++pos; while (pos < sql.length()) { c = sql.charAt(pos); ++pos; if (c == '\"') { break; } } break;
// parse the type of comment case'/': // possible start of '/*' if (pos + 1 < sql.length()) { char c1 = sql.charAt(pos + 1); if (c1 == '*') { startIndex = pos; int end = sql.indexOf("*/", pos + 2); if (end < 0) { end = sql.length(); } else { end += "*/".length(); } pos = end; Integer endIndex = pos; returnnew Comment(startIndex, endIndex); } }