-1

I'm currently looking at building a calculation parser tool for a Rules Engine project.

The calculation takes the form of a string which I was using string.split(' ') to get into an array of values, separating the values and operators:

expression = "5 + 6 - 8"
expression.split(' ');

[0]:5
[1]:+
[2]:6
[3]:-
[4]:8

My code uses this array to get the answer 3 - at the moment I'm just doing left to right evaluation and dealing with operator precedence.

I'm looking to extend the calculation string to work with dates - adding or subtracting minutes from a date time, unfortunately my DateTime has a space so I get the result:

expression = "12/12/2016 12:00:00 + 30 - 10"
expression.split(' ');

[0]:12/12/2016 
[1]:12:00:00
[2]:+
[3]:30
[4]:-
[5]:10

When I really want:

[0]:12/12/2016 12:00:00 
[1]:+
[2]:30
[3]:-
[4]:10

I was hoping to solve this through a regular expression so I could also validate the string at the same time but unfortunately my knowledge of creating them is limited.

Would anyone have an example of a regular expression, or any suggestions on how I could potentially do this - getting the numbers and operators to be stored separately in an array? or is this not possible with regular expressions? would I be better off using String.Substring() instead to pull out the data?

edit
sln solution solved my issue, my final code looked like this:

var splitExp = Regex.Split(expression, @"[ ](?:(?=\D)|(?<=\D[ ]))");

Which gives:

expression = "12/12/2016 12:00:00"
splitExp[0] =  "12/12/2016 12:00:00"

expression = "12/12/2016 12:00:00 + 30 - 10"
splitExp[0] =  "12/12/2016 12:00:00"
splitExp[0] =  "+"
splitExp[0] =  "30"
splitExp[0] =  "-"
splitExp[0] =  "10"

Which is exactly what I was looking for.

QTheIntro
  • 55
  • 10
  • Well, though it sounds too broad, you might try `Regex.Split(expression, @" (?!\d+:)")`. Also, see [*Is there a string math evaluator in .NET?*](http://stackoverflow.com/questions/355062/is-there-a-string-math-evaluator-in-net) – Wiktor Stribiżew Jul 27 '16 at 20:18
  • ^This. Use negative lookaheads to get your regex to match properly. The given code might not be exactly what OP needs, but it can be used as a starting point because it is at least very close to what OP needs. – Kadima Jul 27 '16 at 20:20
  • Also, see [*How to parse math expressions in C#*](http://stackoverflow.com/questions/2853907/how-to-parse-math-expressions-in-c). – Wiktor Stribiżew Jul 27 '16 at 20:23
  • @WiktorStribiżew I noticed the first post but the answers actually do too much for me - they actually do the calculation whereas I'm just looking to pull out the info from the string - as I'm needing it to build a Lamda expression. The second post however I didn't notice and is very interesting - I will look at this if I need to but operator precedence in at some point. Thanks for the pointers – QTheIntro Jul 28 '16 at 08:22

1 Answers1

0

There are more elegant ways of doing this, but you can always substitute a token in for the space in the date as a way of preprocessing the input and then swap the replacement back out for a space when you process the split index. Example: replace (([0-9]{2}/){2}[0-9]{4})( )(([0-9]{2}:){2}[0-9]{2}) with $1@@SPACE@@$4 before you split the string on spaces and then when you process the split string at each index replace @@SPACE@@ with an actual space before continuing.

S.C.
  • 1,152
  • 8
  • 13
  • So swapping out spaces that I don't want to be considered spaces with a special character, something like - "12/12/2016@SPACE@12:00:00 + 30 - 10" and then substituting out @SPACE@ for an actual space before parsing. This would work for me - though I agree it wouldn't be the most elegant... – QTheIntro Jul 28 '16 at 08:12