最近工作需要,要截取一个sql中某个函数,刚好这个函数有括号,将此函数截掉,写了个匹配括号的程序,主要是基于字符串的索引写的
package com.cai.test;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
/**
* @author
*
* 2016年8月21日
*/
public class Bracket {
public static void main(String[] args) {
Bracket bracket = new Bracket();
String sql = "SELECT Flt_Dpt_Dt" +
" ,CASE WHEN Lane_Area IN ('港澳','台湾' ) THEN '港澳台' " +
" ELSE Lane_Area " +
" END AS Flt_Duty_Area " +
" ,SUM (Total_Cap_Qty*Seg_Distance) AS ASK " +
" FROM " +
" (SELECT *" +
" FROM PV_MART.ITM_FLIGHT_BASE T1" +
" WHERE Lane_Type = '国际'" +
" AND Leg_Ind <>'N'" +
" AND (Flt_Dpt_Dt >=DATE '2014-01-01')" +
" QUALIFY ROW_NUMBER() OVER(PARTITION BY Carrier_Cd,Flt_Dpt_Dt,Flt_Nbr,Lane_Area,Orig_Airport_Cd,Dest_Airport_Cd ORDER BY Dcp_Dt ) =1) T1 GROUP BY 1,2";
sql = bracket.formatStrBackspace(sql.replaceAll("QUALIFY ROW_NUMBER\\(\\)", ""));
int index = sql.indexOf("OVER(") + 4;
//System.out.println(index);
String str = "(()()((()())))";
Map<Integer, Integer> bracketIndex = bracket.bracketIndex(sql);
// System.out.println(bracketIndex);
System.out.println(sql.substring(index-4, bracketIndex.get(index)+1));
}
/**
* 对字符串的括号进行配对
* 将字符的左括号和右括号索引进行存储,然后遇见右括号取出
* 步骤:
* 将字符串先进行格式化,多个空格的用单个空格替换
* 根据括号规则分析可知:(()(()()))
* 先取内部括号,后取外部括号
* @param str 字符创
* @param s 匹配的字符
*/
public Map<Integer, Integer> bracketIndex(String str) {
Map<Integer, Integer> indexMap = new HashMap<Integer, Integer>();
List<Integer> leftList = new ArrayList<Integer>();
List<Integer> rightList = new ArrayList<Integer>();
str = formatStrBackspace(str);
char[] chs = str.toCharArray();
for (int i=0;i<chs.length;i++) {
if(chs[i] == '(') {
leftList.add(i);
} else if(chs[i] == ')') {
rightList.add(i);
}
}
//42, 107, 150, 237, 288, 295 53, 134, 268, 289, 397, 401 一次后的结果为 150
if(leftList.size() == rightList.size()) {
int size = leftList.size();
//取出内部括号匹配索引,一对括号的右括号必定在前后两个左括号中间
outter:for(int j=0;j<size;) {
inner:for (int i=0;i<size;i++) {
if(i+1<size) {
if(rightList.get(j) > leftList.get(i) && rightList.get(j) < leftList.get(i+1)) {
indexMap.put(leftList.get(i), rightList.get(j));
leftList.remove(i);
rightList.remove(j);
size--;
break inner;
}
} else {
break outter;
}
}
}
//最后剩余的括号则为外括号,里外对应即可
if(size > 0) {
for(int i=0;i<size;i++) {
indexMap.put(leftList.get(i), rightList.get(size-(i+1)));
}
}
}
return indexMap;//288=289, 237=268, 295=397, 42=53, 107=134, 150=401
}
public String formatStrBackspace(String str) {
return str.replaceAll(" +", " ");
}
}
如果有更好的方法,请提出好的意见。