【问题标题】:Split a complex String based on grouping of small brackets in java基于java中小括号的分组拆分复杂的字符串
【发布时间】:2014-11-17 14:19:54
【问题描述】:

我有一个来自 UI 的复杂字符串,例如:

(region = "asia") AND ((status = null) OR ((inactive = "true") AND (department = "aaaa")) OR ((costcenter = "ggg") OR (location = "india")))

我需要拆分它并在我的代码中使用它,但我必须考虑大括号,以便分组完全如图所示。拆分后,我必须在每次迭代中得到类似以下内容并将其分解

第一次:

(region = "asia") AND 

((status = null) OR ((inactive = "true") AND (department = "aaaa")) OR ((costcenter = "ggg") OR (location = "india")))

第二次:

(region = "asia") AND 

(

(status = null) OR 

((inactive = "true") AND (department = "aaaa")) OR 
((costcenter = "ggg") OR (location = "india"))

)

等等……

关于如何实现这一点的任何指示?

【问题讨论】:

  • 上下文无关语法。考虑使用像 ANTLR 这样的解析器生成器工具。请参阅“可以使用正则表达式匹配嵌套模式吗?”中的类似问题和相关答案。在stackoverflow.com/questions/133601/…
  • 上面评论中的链接指向一个理论答案。但是,是的,您应该为此实现一个解析器。

标签: java regex parsing expression


【解决方案1】:

您似乎不愿意进行成熟的解析,而正则表达式无法解决此类问题,也许是逐步解决方案。

这里解释了一个变量列表,其中 ith 条目的内部文本值为 (...),变量形式为 @123,其中 @987654324 @ 是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));
    }
}

这会给

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

对于完整的解决方案,您可以使用 Java Scripting API 并借用 JavaScript 引擎或制作自己的小型脚本语言,

【讨论】:

  • 我没有在 OP 中看到这一点:“你不愿意进行完整的解析”
  • @AndyThomas:虽然被“似乎……”削弱了,但这种表述确实有点自以为是。也许像 StringTemplate 这样的语法和紧凑的东西也可能是可行的。我的印象:如果 OP 首先想到用正则表达式解决这个问题,那么放弃自上而下解析和语法之类的术语可能不是很有吸引力。 这里已经做了一些解析(在 LISP 级别):redex 评估。
猜你喜欢
  • 1970-01-01
  • 2013-03-30
  • 1970-01-01
  • 2013-02-20
  • 2017-08-24
  • 2021-08-04
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多