正则表达式分组和匹配

时间:2016-11-26 12:53:53

标签: java regex regex-negation regex-lookarounds regex-greedy

我有正则表达式https://regex101.com/r/PPbhRn/1。在这里,我看到"和"被捕获,我能够看到上面也捕捉到一些白色空间。有没有办法摆脱那些白色空间?并且我想知道只有在正确捕获分组时模式是否匹配?

String validRegex="(((?:[(]* ?[a-z][a-z]+ ?[)]*)|[(]* ?(NOT) (?:[(]* ?[a-z][a-z]+ ?[)]*) ?[)]*)( (AND|OR) ((?:[(]* ?[a-z][a-z]+ ?[)]*)|[(]* ?(NOT) (?:[(]* ?[a-z][a-z]+ ?[)]*) ?[)]*))*)";

    String formula = "mean AND trip OR (mean OR mango) AND (mean AND orange) OR mango AND (test OR NOT help)";
    Pattern p1 = Pattern.compile(validRegex, Pattern.CASE_INSENSITIVE | Pattern.DOTALL | Pattern.MULTILINE);
    final Matcher matcher = p1.matcher(formula);

    boolean result=MarketMeasureUtil.isValidFormula(formula);
    System.out.println(result);

    while (matcher.find()) {
        System.out.println("Full match: " + matcher.group(0));
        for (int i = 1; i <= matcher.groupCount(); i++) {
            System.out.println("Group " + i + ": " + matcher.group(i));
            System.out.println( matcher.group() + "starting at" + "index" + matcher.start()+ "and ending at index" +matcher.end() );

        }

我无法正确捕捉群组,我需要捕捉像&#34;意思和旅行&#34;等群组。 &#34; OR&#34; &#34;意思是芒果&#34; ..等等。 isValidFormula()调用regex.matches()。在我们的情况下匹配工作正常。分组无法按预期工作

2 个答案:

答案 0 :(得分:0)

正则表达式不适合此任务。我怀疑如果你可以添加任意数量的大括号,甚至可以验证表达式。

你必须编写一个使用类似的类来构建树的解析器:

class Node {

    boolean[] isAnd = null;
    Node[] children = null;
    String literal = null;

    Node(String literal) { // creator for literals
      this.literal = literal;
    }

    Node(boolean[] isAnd) { // creator for intermediate nodes
      this.isAnd = isAnd;
      children = new Node[isAnd.length + 1];
    }

}

这个方法看起来像这样:

Node parse(String) throws ParseException { // returns the root

首先,您可以通过计算所有大括号来删除右侧和左侧的多余括号,然后您可以找到0级andor s(即那些不在大括号)并创建一个中间节点,如果你没有找到任何0级andor s,那么该字符串必须是文字或无效。如果它是一个中间节点,则通过递归调用parse方法添加子级,并使用0级andor周围的子串。

答案 1 :(得分:0)

看起来你创建了某种DSL。 你应该考虑使用解析器或实现你自己的语言&#34;并不复杂。

我假设您只评估OR / AND操作。它与代码计算器非常相似,其中AND(乘法)优先于OR(加法)。因此,您可以实现自己的。 您可以先对该语句进行标记并对其进行验证,但不要尝试使用正则表达式同时执行这两种操作。如果验证是您可以在此结束的唯一目的。 接下来,如果必须评估表达式,可以使用标记创建二叉树(例如,OR操作数为左叶,AND操作数为右叶),并应用语法来计算表达式。