Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Welcome To Ask or Share your Answers For Others

Categories

0 votes
338 views
in Technique[技术] by (71.8m points)

java - 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

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

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

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

See Question&Answers more detail:os

与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
Welcome To Ask or Share your Answers For Others

1 Reply

0 votes
by (71.8m points)

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
  • Thus, (?<=op)|(?=op) matches everywhere after or before op
    • ... where op is 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

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

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


与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…
OGeek|极客中国-欢迎来到极客的世界,一个免费开放的程序员编程交流平台!开放,进步,分享!让技术改变生活,让极客改变未来! Welcome to OGeek Q&A Community for programmer and developer-Open, Learning and Share
Click Here to Ask a Question

...