简体   繁体   中英

Parsing logical text to Json structure

I receive a java string : "(((x=ss)OR(x=0))AND((y=dd)OR(y=rr))AND(z=1S))" . I need to parse and format it to a json of below structure.

{
  "exp": {
    "typ": "and",
    "sbe": [
      {
        "exp": {
          "typ": "or",
          "vtp": "sta",
          "key": "x",
          "vsa": [
            "ss",
            "0"
          ]
        }
      },
      {
        "exp": {
          "typ": "or",
          "vtp": "sta",
          "key": "y",
          "vsa": [
            "dd",
            "rr"
          ]
        }
      },
      {
        "exp": {
          "typ": "eq",
          "vtp": "str",
          "key": "z",
          "vsa": "1S"
        }
      }
    ]
  }
}

Have been trying with the below java program to split by logical operator. Below is the logic which I have been trying:

  1. check for the balanced bracket.
  2. if yes, extract contents within the bracket.
  3. extract the logical operator (AND or OR)
  4. with the above extracted operator, split the contents into an array/list.
  5. for each content, repeat from the step 1

I am unable to think through what should be the logic to go proceed ahead

public class Tester {
    public static void main(String[] args) throws IOException {
        String input  = "(((x=ss)OR(x=0))AND((y=dd)OR(y=rr))AND(z=1S))";
        if (isExpressionBalanced(input)) {
            System.out.println("input = " + input);
            extractRecursive(input);
        } else {
            System.out.println("The expression is not balanced");
        }
    }

    private static List<String> splitByOperator(String text) {
        Map<String, String > map = new HashMap<>();
        String bracketContents = getWhatsInsideBrackets(text);
        String operator = extractOperator(bracketContents);
        if (operator == null) {
            System.out.println(bracketContents);
            map.put(bracketContents.split("=")[0],  bracketContents.split("=")[1]);
            return Collections.emptyList();
        }
        String[] splitTextArray = bracketContents.split(operator);
        for (String splitText : splitTextArray) {

            System.out.println(operator);

            List<String>  list = splitByOperator(splitText);
            list.size();
        }
        return Arrays.asList(splitTextArray);
    }

    private static void extractRecursive(String text) {
        List<String> splitTextArray = splitByOperator(text);
        for (String splitText : splitTextArray) {
            String bracketContents = getWhatsInsideBrackets(splitText);
            List<String> list = splitByOperator(bracketContents);
            list.size();
        }
    }

    public static String getWhatsInsideBrackets(String stringWithBracket) {
        int firstBracketIndexStart = stringWithBracket.indexOf('(');
        int firstBracketIndexEnd = findClosingParen(stringWithBracket.toCharArray(), firstBracketIndexStart);
        String stringWIthinBrackets = stringWithBracket.substring(firstBracketIndexStart + 1, firstBracketIndexEnd);
        return stringWIthinBrackets;
    }

    private static String extractOperator(String text) {
        String operator = null;
        int innerFirstBracketIndexStart = text.indexOf('(');
        if (innerFirstBracketIndexStart < 0) {
            return operator;
        }
        int innerFirstBracketIndexEnd = findClosingParen(text.toCharArray(), innerFirstBracketIndexStart);
        if (text.startsWith("AND", innerFirstBracketIndexEnd + 1)) {
            operator = "AND";
        } else if (text.startsWith("OR", innerFirstBracketIndexEnd + 1)) {
            operator = "OR";
        }
        return operator;

    }

    public static int findClosingParen(char[] text, int openPos) {
        int closePos = openPos;
        int counter = 1;
        while (counter > 0) {
            char c = text[++closePos];
            if (c == '(') {
                counter++;
            } else if (c == ')') {
                counter--;
            }
        }
        return closePos;
    }

    static boolean isExpressionBalanced(String searchTerm) {
        Stack stack = new Stack();
        for (int i = 0; i < searchTerm.length(); i++) {
            if (searchTerm.charAt(i) == '(') {
                stack.push(searchTerm.charAt(i));
            }
            if (searchTerm.charAt(i) == ')') {
                if (stack.empty()) {
                    return false;
                }
                char top_char = (char) stack.pop();

                if ((top_char == '(' && searchTerm.charAt(i) != ')')) {
                    return false;
                }
            }
        }
        return stack.empty();
    }

}

Unable to think through the split logic and form the expected json structure.

It will be easier if you could parse the string and model those as Java objects first. Then you can easily transform Java object to JSON using Gson.

  1. Create a Java class something like:

     class Expression { String typ; String vtp; // Other stuff }

    This should be able to store your data such as typ , vtp , key and etc.

  2. Parse your expression. Probably in the way Jim Mischel have suggested above in his comment.

  3. After parsing, don't store the contents into an array/list (as you have mentioned in your step 4):

    with the above extracted operator, split the contents into an array/list.

but create a new Expression() for each split content. Something like: new Expression("eq", "str", "z", "15");

  1. Now you will have a Java Object structure of your parsed expressions. You have to convert that Java object to a JSON. Use Gson and convert it to JSON.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM