【问题标题】:How to use Java's regex to split nested mathematical equations如何使用 Java 的正则表达式拆分嵌套的数学方程
【发布时间】:2013-01-13 04:10:12
【问题描述】:

我很好奇如何使用 java 的字符串正则表达式有意义地拆分带括号的数学方程。没有例子很难解释,下面是一个。

一个通用的解决方案模式将受到赞赏,而不是仅适用于下面提供的示例。

String s = "(5 + 6) + (2 - 18)";
// I want to split this string via the regex pattern of "+",
// (but only the non-nested ones) 
// with the result being [(5 + 6), (2 - 18)]

s.split("\\+"); // Won't work, this will split via every plus.

我主要寻找的是第一级拆分,我想要一个正则表达式检查是否像“+”或“-”这样的符号以任何形式嵌套,如果是,不要拆分它,如果它不是分裂它。嵌套可以是 () 或 [] 的形式。

谢谢。

【问题讨论】:

  • 您是否还期望拆分嵌套表达式,例如 ((6 - 5) + 4)?
  • 不,我只需要一级拆分,我想要一个正则表达式检查是否以任何形式嵌套了像“+”或“-”这样的符号,如果是,不要拆分它,如果它不分裂它。嵌套可以是 () 或 [] 的形式。
  • 检查我的答案.. 让我为 [] 添加逻辑。这不是您最初的要求..

标签: java regex string


【解决方案1】:

不幸的是,没有 RegEx,你需要像 JEP 这样的库

【讨论】:

    【解决方案2】:

    如果你不希望像 ((6 + 5)-4) 这样拆分嵌套表达式,我有一个非常简单的函数可以在不使用正则表达式的情况下拆分表达式:

    public static String[] subExprs(String expr) {
        /* Actual logic to split the expression */
        int fromIndex = 0;
        int subExprStart = 0;
        ArrayList<String> subExprs = new ArrayList<String>();
        again:
        while ((subExprStart = expr.indexOf("(", fromIndex)) != -1) {
            fromIndex = subExprStart;
            int substringEnd=0;
            while((substringEnd = expr.indexOf(")", fromIndex)) != -1){
                subExprs.add(expr.substring(subExprStart, substringEnd+1));
                fromIndex = substringEnd + 1;
                continue again; 
            }
        }
    
        /* Logic only for printing */
        System.out.println("Original expression : " + expr);
        System.out.println();
        System.out.print("Sub expressions : [ ");
        for (String string : subExprs) {
            System.out.print(string + ", ");
        }
        System.out.print("]");
        String[] subExprsArray = {};
        return subExprs.toArray(subExprsArray);
    }
    

    Sample output :

    原表达式:(a+b)+(5+6)+(57-6)

    子表达式:[ (a+b), (5+6), (57-6), ]

    编辑

    对于还获取包含在[] 中的表达式的额外条件,此代码将处理()[] 中的表达式。

    public static String[] subExprs(String expr) {
    
        /* Actual logic to split the expression */
        int fromIndex = 0;
        int subExprStartParanthesis = 0;
        int subExprStartSquareBrackets = 0;
        ArrayList<String> subExprs = new ArrayList<String>();
        again: while ((subExprStartParanthesis = expr.indexOf("(", fromIndex)) > -2
                && (subExprStartSquareBrackets = expr.indexOf("[", fromIndex)) > -2) {
    
            /* Check the type of current bracket */
            boolean isParanthesis = false;
            if (subExprStartParanthesis == -1
                    && subExprStartSquareBrackets == -1)
                break;
            else if (subExprStartParanthesis == -1)
                isParanthesis = false;
            else if (subExprStartSquareBrackets == -1)
                isParanthesis = true;
            else if (subExprStartParanthesis < subExprStartSquareBrackets)
                isParanthesis = true;
    
            /* Extract the sub expression */
            fromIndex = isParanthesis ? subExprStartParanthesis
                    : subExprStartSquareBrackets;
            int subExprEndParanthesis = 0;
            int subExprEndSquareBrackets = 0;
            if (isParanthesis) {
                while ((subExprEndParanthesis = expr.indexOf(")", fromIndex)) != -1) {
                    subExprs.add(expr.substring(subExprStartParanthesis,
                            subExprEndParanthesis + 1));
                    fromIndex = subExprEndParanthesis + 1;
                    continue again;
                }
            } else {
                while ((subExprEndSquareBrackets = expr.indexOf("]", fromIndex)) != -1) {
                    subExprs.add(expr.substring(subExprStartSquareBrackets,
                            subExprEndSquareBrackets + 1));
                    fromIndex = subExprEndSquareBrackets + 1;
                    continue again;
                }
            }
        }
    
        /* Logic only for printing */
        System.out.println("Original expression : " + expr);
        System.out.println();
        System.out.print("Sub expressions : [ ");
        for (String string : subExprs) {
            System.out.print(string + ", ");
        }
        System.out.print("]");
        String[] subExprsArray = {};
        return subExprs.toArray(subExprsArray);
    }
    

    Sample Output :

    原表达式:(a+b)+[5+6]+(57-6)-[a-b]+[c-d]

    子表达式:[ (a+b), [5+6], (57-6), [a-b], [c-d], ]

    建议对代码进行改进。 :)

    【讨论】:

    • 当您的问题指定使用正则表达式时,您将此答案标记为正确,这很奇怪。并不是说它实际上是可能的。
    • @EJP 根据不同的答案,Regex 中没有可用的解决方案。此外,作者只想要一层括号。我曾向他询问过嵌套表达式,例如 ((6 + 5) - 3)。所以,我给出了这个答案来减少新库的开销。你觉得对吗?
    【解决方案3】:

    您无法知道您永远不会得到超过一级的括号,并且根据定义,您无法使用正则表达式分析递归语法。您需要使用或编写一个解析器。 为 Dijkstra Shunting Yard 算法,或递归下降表达式解析器,或可以执行上述任一操作的库提供帮助,

    【讨论】:

      猜你喜欢
      • 2015-05-02
      • 1970-01-01
      • 1970-01-01
      • 2013-07-28
      • 1970-01-01
      • 1970-01-01
      • 2011-03-23
      • 2016-07-24
      • 2021-12-04
      相关资源
      最近更新 更多