Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 正则表达式字符串拆分使一个字符优先于另一个字符_Java_Regex - Fatal编程技术网

Java 正则表达式字符串拆分使一个字符优先于另一个字符

Java 正则表达式字符串拆分使一个字符优先于另一个字符,java,regex,Java,Regex,我知道有很多regex帖子,但我无法找到我真正需要的。我正在创建一个计算器应用程序,我有一个方程式,我需要根据方程式中的运算符对其进行标记 示例: “123x849-302+450”->[“123”、“849”、“302”、“450”] “124x(145+301)x402+(-402)”->[“124”、“145+301”、“402”和“-402”] “124x((234+403)/354))+(-21)”->[“124”、“(234+403)/354”、“-21”] 基本上,如果有括号,我需

我知道有很多regex帖子,但我无法找到我真正需要的。我正在创建一个计算器应用程序,我有一个方程式,我需要根据方程式中的运算符对其进行标记

示例:

“123x849-302+450”->[“123”、“849”、“302”、“450”]

“124x(145+301)x402+(-402)”->[“124”、“145+301”、“402”和“-402”]

“124x((234+403)/354))+(-21)”->[“124”、“(234+403)/354”、“-21”]

基本上,如果有括号,我需要在括号内获取标记,否则只需根据运算符进行拆分

我对正则表达式很不熟悉,只知道最基本的内容。我不知道如何在正则表达式中包含括号,现在,我只知道:

String delim = "[x+/-]";
String[] tokens = equation.toString().split(delim);

toString的存在是因为equation是一个StringBuilder。

我认为regexp不是合适的工具。我不知道最终目标是什么,但如果您只需要像问题中那样拆分表达式,您可以尝试以下方法:

private static List<String> splitExpr(String expr) {
    List<String> result = new ArrayList<>();
    StringBuilder buf = new StringBuilder();
    int level = 0;
    int st = 0;
    for (char c: expr.toCharArray()) {
        if (level > 0) {
            // we're in a subexpression
            if (c == '(') {
                ++level;
            } else if (c == ')') {
                --level;
            }
            if (level == 0) {
                result.add(buf.toString());
                st = 2;
            } else {
                buf.append(c);
            }
        } else {
            switch (st) {
                case 0:
                    // initial state
                    if (Character.isDigit(c)) {
                        // first digit of a number
                        buf.setLength(0);
                        buf.append(c);
                        st = 1;
                    } else if (c == '(') {
                        // beginning of a subexpression
                        buf.setLength(0);
                        ++level;
                    } else {
                        // error: ignore unexpected character
                    }
                    break;
                case 1:
                    // inside a number
                    if (Character.isDigit(c)) {
                        // next digit
                        buf.append(c);
                    } else if (c == '+' || c == '-' || c == 'x' || c == 'X'
                            || c == '/') {
                        // operator; the number is finished, add it to the list
                        result.add(buf.toString());
                        st = 0;
                    } else {
                        // error: ignore unexpected character
                    }
                    break;
                case 2:
                    // after a subexpression
                    if (c == '+' || c == '-' || c == 'x' || c == 'X'
                            || c == '/') {
                        st = 0;
                    } else {
                        // error: ignore unexpected character
                    }
                    break;
            }
        }
    }
    if (level == 0 && st == 1) {
        // in a number at the end of string: add the number to the list
        result.add(buf.toString());
    }
    return result;
}

“规则”语法的概念是一个学术概念正则表达式的名称正确:它们可以解析任何“正则”语法,但不能用于解析非正则语法

让我们将“基础数学”定义为数字、4个运算符:
+-*/
和括号的组合

“基础数学”不是正规的

因此,它不能用正则表达式进行解析

您需要的是一个解析器,它可以:

a+x*y+(b-c)*e
在该数据结构中:

          PLUS
      /           \
    PLUS          TIMES
  /     \         /     \
a      TIMES    MINUS   e
      /   \    /  \
      x   y    b   c
可以使用各种解析器技术,例如递归下降或packrat(例如使用grappa/parboiled解析器库),以及各种基于LALR和LL(k)的解析技术,例如ANTLR。一般来说,这些都是非常复杂的技术;也许对于这种琐碎的事情,您可以为此编写自己的基于递归下降的解析

但是,回到你原来的问题,如果你想把
a+x*y+(b-(g+h))*e
分成:[a'、[x'、[y'、“(b-(g+h))、[e'],这只是你需要的部分,因为现在你仍然需要解决如何处理“(b-(g+h))节点,正则表达式根本无法做到这一点:你想让你的正则表达式看到开头
就在
b
之前,作为括号块的开始,然后….正则表达式必须计算开始部分的数量,然后找到尽可能多的结束部分并忽略它们,然后在这些结束部分胜出后再计算结束部分。因此,此正则表达式:

String elementPattern = "(\\([^\\)]+\\)|[^-+*/\\(\\)]+)";
Pattern p = Pattern.compile("^\\s*" + elementPattern + "(\\s*[-+*/]\\s*" + elementPattern + ")*$");

乍一看似乎能完成任务,但实际上却不能完成任务:它会停止考虑
(b-(g+h))部分在2个关闭的括号中的第一个,因此不能匹配。它需要在第二个停止,但是正则表达式没有任何方式去做,因为这不是“正则”。< /P>也许不是你需要的ReGEXP……我还能用什么?模式匹配器?我也不熟悉。我会使用递归下降法。谢谢你把这件事弄清楚!我会好好读一读的。
String elementPattern = "(\\([^\\)]+\\)|[^-+*/\\(\\)]+)";
Pattern p = Pattern.compile("^\\s*" + elementPattern + "(\\s*[-+*/]\\s*" + elementPattern + ")*$");