I have a complex string coming from the UI like:
(region = \"asia\") AND ((status = null) OR ((inactive = \"true\") AND (department = \"aaaa\")) OR ((costcenter
As it seems you are not willing to go in full-fledged parsing, and regex cannot tackle this kind of problem, maybe a step-wise solution.
Here a list of variables is construed, where the ith entry has the inner text value of (...)
with variables of the form @123
where 123
is the i
.
static String parse(String exp, List<String> vars) {
final Pattern BRACED_REDEX = Pattern.compile("\\(([^()]*)\\)");
for (;;) {
Matcher m = BRACED_REDEX.matcher(exp);
if (!m.find()) {
break;
}
String value = m.group(1);
String var = "@" + vars.size();
vars.add(value);
StringBuffer sb = new StringBuffer();
m.appendReplacement(sb, var);
m.appendTail(sb);
exp = sb.toString();
}
vars.add(exp); // Add last unreduced expr too.
return exp;
}
public static void main(String[] args) {
String exp = "(region = \"asia\") AND ((status = null) OR ((inactive = \"true\") "
+ "AND (department = \"aaaa\")) OR ((costcenter = \"ggg\") OR "
+ "(location = \"india\")))";
List<String> vars = new ArrayList<>();
exp = parse(exp, vars);
System.out.println("Root expression: " + exp);
for (int i = 0; i < vars.size(); ++i) {
System.out.printf("@%d = %s%n", i, vars.get(i));
}
}
This will give
Root expression: @0 AND @8
@0 = region = "asia"
@1 = status = null
@2 = inactive = "true"
@3 = department = "aaaa"
@4 = @2 AND @3
@5 = costcenter = "ggg"
@6 = location = "india"
@7 = @5 OR @6
@8 = @1 OR @4 OR @7
@9 = @0 AND @8
For a full fledged solution you could use the Java Scripting API and either borrow the JavaScript engine or make your own small Scripting language,