1

I have a string that looks like this:

-2.2,1.1-6.9,2.3-12.8,2.3

And I want to write a function ParseString() which would return a list of doubles with these elements:

-2.2
1.1
-6.9
2.3
-12.8
2.3

The problem I have is that the minus sign is acting like a delimiter, but also has semantic meaning (signifies negative number). I am quite inexperienced with regular expressions and I am stuck on this. Can any expert out there help me out with this? I am writing this in C#.

Adam S
  • 8,245
  • 17
  • 60
  • 95
  • The number of wrong answers here was _horrifying_. **Read the question**! – SLaks Feb 25 '11 at 15:33
  • I hope you are sure of the semantic meaning of the minus, because looking from here it seems to be a range (so -2.2, 1.1 to 6.9, 2.3 to 12.8, 2.3). – xanatos Feb 25 '11 at 17:06

3 Answers3

6

You can split on the regex ,|(?<!^|,)(?=-).
Tested example:

var splitter = new Regex(@",|(?<!^|,)(?=-)");
var numbers = splitter.Split(@"-2.2,1.1-6.9,2.3,-12.8,2.3")
                      .Select(Double.Parse);

Explanation

This regex matches either , or (?<!^|,)(?=-).

(?!^)(?=-) is a pair of zero-width assertions that matches before a - that isn't at the beginning of the string or after a comma.
(?<!^|,) is a negative lookbehind that prevents it from matching after the beginning of the string or a comma. Without this negation, it will return extra empty strings.
(?=-) is a positive lookahead that forces it to match right before a -.

SLaks
  • 800,742
  • 167
  • 1,811
  • 1,896
  • I can't test this immediately, but I wanted to thank you for taking the time to point out the issues in other responses. What's the point of this community if its full of wrong answers? Thanks! – Adam S Feb 25 '11 at 15:33
  • This community is quite ok. If it wouldn't be ok, nobody would have pointed out the problems with the other answers. Answers here are happening so fast, most of the time, people simply don't have the time to test every answer! – Daniel Hilgarth Feb 25 '11 at 15:34
  • I agree Daniel, I was saying that SLaks' extra effort is what makes it great. – Adam S Feb 25 '11 at 15:48
5

A simple solution (not the most efficient) is to first replace "-" with ",-" and then split on "," and finally parse the parts. Like this:

string numStr = "-2.2,1.1-6.9,2.3-12.8,2.3";
string[] splitNumStr = numStr.Replace("-", ",-").Split(',');
List<double> nums = splitNumStr.Select(s => double.Parse(s)).ToList();
Yhrn
  • 1,045
  • 7
  • 14
0

This regex works for me: (-*\d*\.\d*)|(-\d*\.\d*-\d*\.\d*)

SLaks
  • 800,742
  • 167
  • 1,811
  • 1,896
Kell
  • 3,037
  • 17
  • 19