1

I have a simple arithmetic expression containing integers, parentheses, and +-*/. Like this:

((1+33)()(4+(3-5)))

What I need to do is split this expression to the string[] like this:

{(, (, 1, +, 33, ), (, ), (, 4, +, (, 3, -, 5, ), ), )}

I am trying to do it with Regex class

public string[] SplitString(string str)
{
     return Regex.Split(str, "(?<=[()-+*/])|(?=[()-+*/])");
}

But output data is not quite right:

{(, (, 1, +, 33, ), (, ), (, 4, +, (, **3-5**, ), ), )}

Lloyd
  • 29,197
  • 4
  • 84
  • 98
Kirill Ludcev
  • 73
  • 2
  • 9
  • 1
    You can compute the result without splitting it. Is this what you are after ? – Zein Makki Jul 23 '16 at 11:49
  • 1
    Note that `)-+` create a range in your char class that matches more than you might expect. Put the hyphen at the end of the character class. – Wiktor Stribiżew Jul 23 '16 at 11:54
  • 1
    Beside that unescaped dash, I suggest to consider to do the other way: match the desired tokens and return a list of all matches - you'll end up with a simpler regex: `return Regex.Matches(str, @"([()+*/-]|\d+)").Cast().Select(m => m.Value).ToArray();` – Dmitry Egorov Jul 23 '16 at 12:07

2 Answers2

1

If it's just the 3-5 causing you problems, you need to escape the "-" in your pattern i.e.

Regex.Split(str, "(?<=[()\\-+*/])|(?=[()\\-+*/])")
George Helyar
  • 4,319
  • 1
  • 22
  • 20
1

If you want to match a dash, it needs to be in the first or the last position in a character class in regex:

(?<=[()+*/-])|(?=[()+*/-])
//        ^            ^

Otherwise, it is interpreted as a character range - in your case, from ) to *.

Demo.

Sergey Kalinichenko
  • 714,442
  • 84
  • 1,110
  • 1,523