Search code examples
c#regexsplit

How to separate numbers from math operators with negative numbers correctly processed


I need to split string input to 2 lists in C#, using RegEx. One must contain numbers, the other mathematical operators.

For example, the string "-9+9+8" should split into ["-9", "9", "8"] and ["+", "+"]. Parentheses are handled by a separate function.

At first I tried this:

List<string> textSplit = Regex.Split(input, "[*/+-]").ToList();
List<string> operators = Regex.Matches(input, "[*/+-]")
                              .Cast<Match>()
                              .Select(m => m.Value).ToList();

But I still can't figure out how to handle negative values correctly.

For example, to divide "8--4"

  • not into ["8", "", "4"] and ["-", "-"],
  • but to ["8", "-4"] and ["-"] instead

Update: The closest option I have right now is (?<=[-+\/*])-?\d|^\d plus (?<=\d)[-+\/*] . Huge gratitude to zmehall. But the solution is still slightly incomplete. From string "-5+8*2/4--6" It correctly highlights the math operators: ["+", "*", "/", "-"], but not quite correctly separates the numbers: ["5", "8", "2", "4", "-6"]. Now I'm thinking about solving this problem.

Update2: From the phone I did not notice the answer from Keszas. Took part of the solution from him, the question is closed. Many thanks to everyone for the help.


Solution

  • I've worked on this for a bit, and I think I found a solution that works (using two separate patterns).

    To capture the numbers (with signs), you can use the expression (?<=[-+\/*])-?\d|^\d

    To capture the operations, you can use the expression (?<=\d)[-+\/*]

    Explanation:

    (?<=[-+\/*]) : match only if there is a sign before
    -? : match an optional negative sign (if above is true)
    \d : match a single digit
    |^\d : match the above, or if the number is the beginning of a line
    
    
    (?<=\d) : match only if there is a digit before
    [-+\/*] : match either `-`, `+`, `/`, `*` (only if above condition is met)
    

    Please let me know if there are any issues with my solution.

    Examples:

    https://regex101.com/r/Kp9lCT/1

    https://regex101.com/r/NGOhY3/1