简体   繁体   English

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

[英]Splitting a simple maths expression with regex

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 \\b will work on 1+2+3 however 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})分割,但它没有在小数点上分割

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|that is alternation this|that是交替
  • Thus, (?<=op)|(?=op) matches everywhere after or before op因此, (?<=op)|(?=op)到处之后或之前匹配op
    • ... where op is replaced by [-+*/()] , ie a character class that matches operators ... 其中op被替换为[-+*/()] ,即匹配运算符的字符类
      • Note that - is first here so that it doesn't become a range definition meta character请注意-在这里是第一个,这样它就不会成为范围定义元字符

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相关问题

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.我把它留下来让它变得简单。

Use match, instead of split:使用匹配而不是拆分:

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

This regex will also accept valid floats like: 1.2e+3 * 2 which should equal 2400 .此正则表达式也将接受有效的浮点数,例如: 1.2e+3 * 2应等于2400 the regexes given by the other respondents will fail.其他受访者给出的正则表达式将失败。

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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM