java 使用正则表达式拆分简单的数学表达式

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3373885/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-10-30 01:33:27  来源:igfitidea点击:

Splitting a simple maths expression with regex

javaregexmath

提问by sutoL

I am trying to have a regular expression split on equations like 1.5+4.2*(5+2) with operators - + * / so the output would be input into a array so I can parse individually

我正在尝试使用运算符 - + * / 在 1.5+4.2*(5+2) 等等式上拆分正则表达式,以便将输出输入到数组中,以便我可以单独解析

[0]1.5
[1]+
[2]4.2
[3]*
[4](
[5]5
[6]+
[7]2
[8]) 

I have found out that the \bwill work on 1+2+3however if I were to have decimal points it would not split.

我已经发现,在\b将工作于1+2+3但是如果我有它不会分裂小数点。

I have tried splitting with \b(\.\d{1,2})however it does not split on the decimal point

我试过拆分,\b(\.\d{1,2})但它不会在小数点上拆分

回答by polygenelubricants

You can use zero-width matching lookahead and lookbehind combo as alternates.

您可以使用零宽度匹配前瞻和后视组合作为替代。

    String equation = "1.5+4.2*(5+2)";

    String regex = "(?<=op)|(?=op)".replace("op", "[-+*/()]");

    // actual regex becomes (?<=[-+*/()])|(?=[-+*/()])

    System.out.println(java.util.Arrays.toString(
        equation.split(regex)
    ));
    //  ___  _  ___  _  _  _  _  _  _
    // [1.5, +, 4.2, *, (, 5, +, 2, )]

Explanation

解释

  • […]is a character class definition
  • (?<=…)is a lookbehind; it asserts that we can match to the left
  • (?=…)is a lookahead; it asserts that we can match to the right
  • this|thatis alternation
  • Thus, (?<=op)|(?=op)matches everywhere after or before op
    • ... where opis replaced by [-+*/()], i.e. a character class that matches operators
      • Note that -is first here so that it doesn't become a range definition meta character
  • […]是字符类定义
  • (?<=…)是回顾;它断言我们可以匹配到左边
  • (?=…)是一个前瞻;它断言我们可以匹配到右边
  • this|that是交替
  • 因此,(?<=op)|(?=op)匹配之后或之前的任何地方op
    • ... whereop被替换为[-+*/()],即匹配运算符的字符类
      • 请注意,-这里是第一个,这样它就不会成为范围定义元字符

References

参考

Related questions

相关问题



More examples of zero-width matching regex for splitting

用于拆分的零宽度匹配正则表达式的更多示例

Here are more examples of splitting on zero-width matching constructs; this can be used to split a string but also keep delimiters.

以下是在零宽度匹配构造上拆分的更多示例;这可用于拆分字符串,但也可以保留分隔符。

Simple sentence splitting, keeping punctuation marks:

简单的分句,保留标点符号:

    String str = "Really?Wow!This.Is.Awesome!";
    System.out.println(java.util.Arrays.toString(
        str.split("(?<=[.!?])")
    )); // prints "[Really?, Wow!, This., Is., Awesome!]"

Splitting a long string into fixed-length parts, using \G

将长字符串拆分为固定长度的部分,使用 \G

    String str = "012345678901234567890";
    System.out.println(java.util.Arrays.toString(
        str.split("(?<=\G.{4})")
    )); // prints "[0123, 4567, 8901, 2345, 6789, 0]"

Split before capital letters (except the first!)

在大写字母前拆分(第一个除外!)

    System.out.println(java.util.Arrays.toString(
        "OhMyGod".split("(?=(?!^)[A-Z])")
    )); // prints "[Oh, My, God]"

A variety of examples is provided in related questions below.

下面的相关问题提供了各种示例。

Related questions

相关问题

回答by Marimuthu Madasamy

Pattern pattern = Pattern.compile("((\d*\.\d+)|(\d+)|([\+\-\*/\(\)]))");
Matcher m = pattern.matcher("1.5+4.2*(5+2)/10-4");
while(m.find()) {
    System.out.printf("%s ", m.group());
}

output: 1.5 + 4.2 * ( 5 + 2 ) / 10 - 4

You can also use ?: to avoid capturing groups. I left it to make it simple.

您还可以使用 ?: 来避免捕获组。我把它留下来让它变得简单。

回答by bcosca

Use match, instead of split:

使用匹配而不是拆分:

(?:\d+\.)?\d*(?:e[+\-]?\d+)?|[\s\-\/()+*%=]

This regex will also accept valid floats like: 1.2e+3 * 2which should equal 2400. the regexes given by the other respondents will fail.

此正则表达式还将接受有效的浮点数,例如:1.2e+3 * 2which should equal 2400。其他受访者给出的正则表达式将失败。

回答by Allain Lalonde

Split the string using [+-/*()].

使用 拆分字符串[+-/*()]