user1442073
user1442073

Reputation: 37

C# Regex.Match to decimal

I have a string "-4.00 %" which I need to convert to a decimal so that I can declare it as a variable and use it later. The string itself is found in string[] rows. My code is as follows:

foreach (string[] row in rows)
{
string row1 = row[0].ToString();
Match rownum = Regex.Match(row1.ToString(), @"\-?\d+\.+?\d+[^%]");
string act = Convert.ToString(rownum); //wouldn't convert match to decimal
decimal actual = Convert.ToDecimal(act);
textBox1.Text = (actual.ToString());
}

This results in "Input string was not in a correct format." Any ideas?

Thanks.

Upvotes: 0

Views: 2233

Answers (3)

WickyNilliams
WickyNilliams

Reputation: 5308

Here's a modified version of your code that changes the regex to use a capturing group and explicitly look for a %. As a consequence, this also simplifies the parsing to decimal (no longer need an intermediary string):

EDIT : check rownum.Success as per executor's suggestion in comments

string[] rows = new [] {"abc -4.01%", "def 6.45%", "monkey" };

foreach (string row in rows)
{
    //regex captures number but not %
    Match rownum = Regex.Match(row.ToString(), @"(\-?\d+\.+?\d+)%");

    //check for match
    if(!rownum.Success) continue;

    //get value of first (and only) capture
    string capture = rownum.Groups[1].Value;

    //convert to decimal
    decimal actual = decimal.Parse(capture);

    //TODO: do something with actual
}

Upvotes: 2

glenatron
glenatron

Reputation: 11362

I see two things happening here that could contribute.

You are treating the Regex Match as though you expect it to be a string, but what a Match retrieves is a MatchGroup.

Rather than converting rownum to a string, you need to lookat rownum.Groups[0].

Secondly, you have no parenthesised match to capture. @"(\-?\d+\.+?\d+)%" will create a capture group from the whole lot. This may not matter, I don't know how C# behaves in this circumstance exactly, but if you start stretching your regexes you will want to use bracketed capture groups so you might as well start as you want to go on.

Upvotes: 3

Joel Etherton
Joel Etherton

Reputation: 37533

If you're going to use the Match class to handle this, then you have to access the Match.Groups property to get the collection of matches. This class assumes that more than one occurrence appears. If you can guarantee that you'll always get 1 and only 1 you could get it with:

string act = rownum.Groups[0];

Otherwise you'll need to parse through it as in the MSDN documentation.

Upvotes: 1

Related Questions