java 字符串 大括号_字符串解析其中的嵌套大括号
发布日期:2021-06-24 11:53:27 浏览次数:2 分类:技术文章

本文共 2389 字,大约阅读时间需要 7 分钟。

从字符串中解析出 ${****},其中{}中间可能还有大括号。

/*算法1: * 1.寻找${,没找到,直接返回空列表

* 2.找到${,从${中的$所在索引位置向后找第一个}

* 3.在${和其后第一个}的字符串间进行探测,如果存在另外的{,有几个则往后推几个}

* 4.在第一个}和推后的}之间进行探测,如果存在{,有几个把最后的}向后推几个,重复此步,直到中间没有{

* 5.此时${和推后的}即为一个合法的公式区域段

*/

/*算法2:

* 1.按${将字符串分块

* 2.在每个块中执行如下逻辑:把${标记为2,单独的{标记为1,}标记为-1。依次标记

* 3.在每块中按照索引顺序从左向右加,如果标记值之和为1,说明${}是闭合合法的。处理下一个块

*/

/**

* 获取字符串中匹配的宏公式(不支持宏公式嵌套,如${ ${}}形式是不合法的,将忽略左侧的${)

* @param str待匹配字符串

* @return{@link ExressionRange}列表

*/

public static List match$Exprs(String str){

/*算法:

* 1.按${将字符串分块

* 2.在每个块中执行如下逻辑:把${标记为2,单独的{标记为1,}标记为-1。依次标记

* 3.在每块中按照索引顺序从左向右加,如果标记值之和为1,说明${}是闭合合法的。处理下一个块

*/

List ranges = new ArrayList();

if(StringUtils.isEmpty(str)) return ranges;

int offset = 0;

int start = str.indexOf("${",offset);

if(start == -1){

return ranges;

}

List indexMap = new ArrayList();

indexMap.add(new IndexObject(start, 2));

offset = start + 2;

while((start = str.indexOf("${", offset)) != -1){

indexMap.add(new IndexObject(start, 2));

offset = start + 2;

}

for(int i=0,size = indexMap.size();i

int left = indexMap.get(i).index;

int right = i == size-1 ? str.length() : indexMap.get(i+1).index;

int offset2 = left + 2,offset3 = left + 2;

int lk,rk;

while((lk = str.indexOf("{",offset2)) < right && lk != -1){

indexMap.add(new IndexObject(lk, 1));

offset2 = lk + 1;

}

while((rk = str.indexOf("}",offset3)) < right && rk != -1){

indexMap.add(new IndexObject(rk, -1));

offset3 = rk + 1;

}

}

return analysisExpressionRanges(ranges,indexMap,str);

}

/**

* 生成ExpressRange列表

* @param ranges待输出的ExpressRange列表

* @param indexMap索引标志小对象列表

* @param originalStr原始字符串

* @return 解析后的ExpressRange列表

*/

private static List analysisExpressionRanges(List ranges,List indexMap,String originalStr){

Collections.sort(indexMap);

int sum = 0,current$L = -1;

for(IndexObject idx:indexMap){

//每块的第一个标志必定是${

if(idx.ratio == 2){

current$L = idx.index;

}

sum += idx.ratio;

//累加和 = 1 并且本块尚未处理完成

if(sum == 1 && current$L !=-1){

ranges.add(new ExpressionRange(current$L, idx.index + 1, originalStr.substring(current$L, idx.index + 1)));

sum = 0;//清空累加只

current$L = -1;//标记本块处理完成,防止 出现 2+1-1-1 + 1-1 被误记的情况

}

}

return ranges;

}

/**

* 索引标志小对象

* @author wangtengfei

*/

private static class IndexObject implements Comparable{

int index;//当前标志在原字符串中的索引

int ratio;//系数

IndexObject(int index,int ratio){

this.index = index;

this.ratio = ratio;

}

public int compareTo(IndexObject o) {

return index - o.index;

}

}

转载地址:https://blog.csdn.net/weixin_32601635/article/details/114068987 如侵犯您的版权,请留言回复原文章的地址,我们会给您删除此文章,给您带来不便请您谅解!

上一篇:java内存排序_Java内存模型之重排序
下一篇:java nio 线程_基于事件的 NIO 多线程服务器

发表评论

最新留言

第一次来,支持一个
[***.219.124.196]2024年04月11日 03时52分54秒