【问题标题】:Parsing logical text to Json structure将逻辑文本解析为 Json 结构
【发布时间】:2019-07-21 13:35:33
【问题描述】:

我收到一个 java 字符串:"(((x=ss)OR(x=0))AND((y=dd)OR(y=rr))AND(z=1S))"。 我需要将其解析并格式化为以下结构的 json。

{
  "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"
        }
      }
    ]
  }
}

一直在尝试使用以下 java 程序按逻辑运算符进行拆分。 以下是我一直在尝试的逻辑:

  1. 检查平衡支架。
  2. 如果是,提取括号内的内容。
  3. 提取逻辑运算符(AND 或 OR)
  4. 使用上面提取的运算符,将内容拆分为数组/列表。
  5. 对于每个内容,从步骤 1 开始重复

我无法思考继续前进的逻辑应该是什么

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();
    }

}

无法思考拆分逻辑,形成预期的json结构。

【问题讨论】:

  • 你可以使用Shunting-yard algorithm来解析这个。您必须更改它以使用ANDOR 等,并更改优先规则,但它基本上是相同的算法。这将为您提供易于格式化的后缀表达式。

标签: java json algorithm parsing data-structures


【解决方案1】:

如果您可以先解析字符串并将其建模为 Java 对象,将会更容易。然后,您可以使用 Gson 轻松地将 Java 对象转换为 JSON。

  1. 创建一个类似的 Java 类:

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

    这应该可以存储您的数据,例如typvtpkey 等。

  2. 解析您的表达式。可能是Jim Mischel 在他的评论中建议的方式。

  3. 解析后,不要将内容存储到数组/列表中(正如您在第 4 步中提到的那样):

    使用上面提取的运算符,将内容拆分为 数组/列表。

但为每个拆分内容创建一个new Expression()。 比如:new Expression("eq", "str", "z", "15");

  1. 现在您将拥有已解析表达式的 Java 对象结构。您必须将该 Java 对象转换为 JSON。使用 Gson 并将其转换为 JSON。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-10-26
    • 2023-03-16
    • 1970-01-01
    相关资源
    最近更新 更多