`

java 括号匹配

    博客分类:
  • java
 
阅读更多

最近工作需要,要截取一个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(" +", " ");
	}
}

 如果有更好的方法,请提出好的意见。

分享到:
评论

相关推荐

Global site tag (gtag.js) - Google Analytics