中缀逻辑表达式解析成前缀逻辑表达式代码--java(以elasticsearch搜索为例)

本文代码用递归的方式去对中缀表达式进行解析,大体上实现了中缀表达式到前缀表达式的解析。

只是在一些细节上要根据自己的需求来进行修改。

还有优化方便如果有耐心可以根据这个方法慢慢该,以实现业务的需求。

在范围转换的地方要修改。(修改为自己的逻辑即可)

这个代码只是转成es的一种json的搜索语法。由于es的json的表达式里面有and和or表达,所以我解析的中缀表达式的逻辑或和与用||和&&表示。具体的优化可不就是这一点代码就能搞定的。这只是来示例解析中缀表达式的方法。

下面代码如下:

public class StrToEsUtil {

    public static String StrToEs(String s){
        StringBuffer sb = new StringBuffer();
        sb.append("{\"query\":");
        sb.append(aaa(s));
        sb.append('}');

        return sb.toString();
    }

    public static String aaa(String s){
        char[] chars = s.toCharArray();

        for(int i=0;i<chars.length;i++){
            if(chars[i]=='('){
                int e=0;
                StackUtil stack = new StackUtil();//栈工具
                stack.pop('(');
                for(int j=i+1;j<chars.length;j++){
                    if(chars[j]=='('){
                        stack.pop('(');
                    }else if(chars[j]==')'){
                        stack.push();
                        if(stack.isEmpty()){
                            e=j;
                            break;
                        }
                    }
                }
                String ss=new String(chars,i+1,e-i-1);
                String s1 = aaa(ss);
                StringBuffer sb = new StringBuffer(new String(chars));
                sb.delete(i,e+1);
                sb.insert(i,s1);
                i=i+s1.length();
                aaa(sb.toString());
                chars=sb.toString().toCharArray();
            }
        }
        for(int i=chars.length-2;i>0;i--){
            if(chars[i]=='|'&&chars[i+1]=='|'&&chars[i-1]==' '&&chars[i+2]==' '){
                StringBuffer sb = new StringBuffer();
                sb.append("{\"or\":[");
                sb.append(field(new String(chars,i+3,chars.length-i-3)));
                sb.append(',');
                sb.append(aaa(new String(chars,0,i-1)));
                sb.append("]}");
                return sb.toString();
            }else if(chars[i]=='&'&&chars[i+1]=='&'&&chars[i+2]==' '&&chars[i-1]==' '){
                StringBuffer sb = new StringBuffer();
                sb.append("{\"and\":[");
                sb.append(field(new String(chars,i+3,chars.length-i-3)));
                sb.append(',');
                sb.append(aaa(new String(chars,0,i-1)));
                sb.append("]}");
                return sb.toString();
            }
        }
        return field(new String(chars));
    }
    public static String field(String f){
        char[] chars = f.replace(" ","").toCharArray();
        StringBuffer sb=new StringBuffer();
        sb.append('{');
        sb.append('"');
        int n=0;
        int len=0;
        for(int i=0;i<chars.length;i++){
            if(chars[i]=='='||chars[i]=='≈'){
                n=i+1;
                len=chars.length-n;
                if(chars[i]=='=')
                {sb.append("term\":{\"");}
                else{sb.append("wildcard\":{\"");}
                sb.append(chars,0,i);
                sb.append("\":\"");
                sb.append(chars,n,len);
                sb.append("\"}}");
                return sb.toString();
            }else if(chars[i]=='!'&&(chars[i+1]=='='||chars[i+1]=='≈')){
                n=i+2;
                len=chars.length-n;
                sb.append("not\":{\"");
                if(chars[i+1]=='='){sb.append("term\":{\"");}
                else{sb.append("wildcard\":{\"");}
                sb.append(chars,0,i);
                sb.append("\":\"");
                sb.append(chars,n,len);
                sb.append("\"}}}");
                return sb.toString();
            }else if(chars[i]=='<'||chars[i]=='>'){
                sb.append("range\":{\"") ;
                n=i+1;
                int e=0;
                int len1=0;
                if(chars[i]=='<'){
                    for(int j=i+1;j<chars.length;j++){

                        if(chars[j]=='<'){

                            len=j-i;
                            e=j+1;
                            len1=chars.length-j;
                            break;
                        }
                        len=chars.length-i;
                    }
                    sb.append(chars,n,len-1);
                    sb.append("\":{\"gt\":\"");
                    sb.append(chars,0,i);
                    if(e!=0){
                        sb.append("\",\"lt\":\"");
                        sb.append(chars,e,len1-1);
                    }
                    sb.append("\"}}}");
                    return sb.toString();
                }
                if(chars[i]=='>'){
                    for(int j=i+1;j<chars.length;j++){

                        if(chars[j]=='>'){

                            len=j-i;
                            e=j+1;
                            len1=chars.length-j;
                            break;
                        }
                        len=chars.length-i;
                    }

                    sb.append(chars,n,len-1);
                    sb.append("\":{\"lt\":\"");
                    sb.append(chars,0,i);
                    if(e!=0){
                        sb.append("\",\"gt\":\"");
                        sb.append(chars,e,len1-1);
                    }
                    sb.append("\"}}}");
                    return sb.toString();
                }
            }
        }
        return f;
    }
}

写个main方法运行一下:



  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值