中缀逻辑表达式解析成前缀逻辑表达式代码--java(以elasticsearch搜索为例)
2018-03-06 18:23
555 查看
本文代码用递归的方式去对中缀表达式进行解析,大体上实现了中缀表达式到前缀表达式的解析。
只是在一些细节上要根据自己的需求来进行修改。
还有优化方便如果有耐心可以根据这个方法慢慢该,以实现业务的需求。
在范围转换的地方要修改。(修改为自己的逻辑即可)
这个代码只是转成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方法运行一下:
只是在一些细节上要根据自己的需求来进行修改。
还有优化方便如果有耐心可以根据这个方法慢慢该,以实现业务的需求。
在范围转换的地方要修改。(修改为自己的逻辑即可)
这个代码只是转成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方法运行一下:
相关文章推荐
- java中解析逻辑表达式的两种方法比较
- 前缀、中缀、后缀表达式及其相互转化的Java实现
- 优酷电视剧爬虫代码实现一:下载解析视频网站页面(4)补充: Java正则表达式Matcher.group(int group)相关类解析
- 你不知道的秘密——深入解析前缀,中缀,后缀表达式
- java 使用 ScriptEngineManager 解析逻辑表达式
- 前缀、中缀、后缀表达式及其相互转化的Java实现
- java解析逻辑表达式
- 解决XDoclet解析Java 5泛型代码出错
- 利用正则表达式获取特定文件(如java class)并对其进行处理(如代码统计)
- 用正则表达式和java解析csv文件
- 3、java设置Linux系统时间之 正则表达式解析时间 及总结
- Java正则表达式获取网址和链接文字解析
- 中缀,前缀,后缀表达式
- Java代码生成和解析xls文件
- 基于表达式解析的计算器程序代码已经上传
- Java解析正则表达式
- 文件上传时生成“日期+随机数”式文件名前缀的Java代码
- 如何用Java 实现 Excel 表达式的解析(摘自:http://topic.csdn.net/t/20030408/17/1634982.html#)
- java正则表达式应用的实例代码
- java代码解析2