0

i'm trying to get Color information that i've stored in a text file and then use that color as the forecolor for a label. BUT, at run time when i click the button to do it, it doesnt give me any error messages or anything. the code i have is below:

MatchCollection lines = Regex.Matches(File.ReadAllText(Path), @"(.+?)\r\n""([^""]+)""\r\n(\d+),\s(\d+)\r\n([\w\s]*)\r\n(\d+\.\d+)""\r\n(\d+?)");
        foreach (Match match in lines)
            int color = Int32.Parse(match.Groups[5].Value);

I have other regex for other info inn files too, but the other regex isnt the problem. the problem is the regex that i have just added to try and match a color (argb). it's at the end of the string:

\r\n(\d+?)

So as far as I understand it, the above little regex thing means this: "Find a carriagereturn and newline, and then 1 or more digits but dont be greedy". is that right?

can somebody please help me with this. thank you very much.

Note: The color info that is saved in the text file is a negative number (ARGB color):

-16744193

The file contents is like this:

Control
Control Text
Control Location
Control Font Name
Control Font Size
Control Font Color

Explanation:

Label
"this is a label"
23, 77
Tahoma
14.0
-55794414

So, the regex works, it gets all the other details correctly but it just doesnt get the color information.

jay_t55
  • 11,362
  • 28
  • 103
  • 174
  • 1
    If you write match.Groups[5].Value to the console what does it output? – ChaosPandion Oct 03 '09 at 00:01
  • Update your question with a sample from your input and show us what you expect to match. As it is now, your regex doesn't support the number of groups you're referring to. – Ahmad Mageed Oct 03 '09 at 00:08

7 Answers7

7

- is not matched by \d. Also, if you do a non-greedy match on \d+ only the first digit will be captured since that satisfies the regexp. Change your regexp into (-?\d+) to match an optional - at the start of your number and as many digits as there are in the number, up to (but not including) the character following the number (newline, end-of-string, ...).

Wim
  • 11,091
  • 41
  • 58
  • thank you @Wim. i have updated it, but with No luck. the regex i have now is: @"(.+?)\r\n""([^""]+)""\r\n(\d+),\s(\d+)\r\n([\w\s]*)\r\n(\d+\.\d+)""\r\n(-?\d+)" --- and the code i have to convert it to system.drawing.color is: int fcolor = Int32.Parse(match.Groups[7].Value); int F_Color = Convert.ToInt32(fcolor); Color ControlForeColor = Color.FromArgb(fcolor); – jay_t55 Nov 05 '09 at 14:46
  • And you have "" before the last \r\n, try this: --> (.+)\r\n""([^""]+)""\r\n(\d+),\s(\d+)\r\n([\w\s]*)\r\n(\d+\.\d+)\r\n(-?\d+) <-- the result is in group 7 btw ;) – Stormenet Nov 05 '09 at 14:56
  • thank you for helping @Stormenet, but it still doesn't want to work :( any ideas? – jay_t55 Nov 05 '09 at 15:05
6

Try this regex and see if it works.

(.+?)\r\n""([^""]+)""\r\n(\d+),\s(\d+)\r\n([\w\s]*)\r\n(\d+.\d+)\r\n(-?\d+)

Your regex appeared to be looking for the " after the font size value.

Also, your ARGB colour will be in group match 7, not 5.

William
  • 8,007
  • 5
  • 39
  • 43
  • @baeltazor I've tested this code in RegexBuddy and it matches your sample with matches for each Group as expected. – William Nov 05 '09 at 15:13
1

I'd set a breakpoint on the line with the error and see what match.Groups[5].Value really is.

I'm betting it can't be converted to an int.

Jay Riggs
  • 53,046
  • 9
  • 139
  • 151
  • i've tried double float string i've even tried coffee and nothing converts to anything on that line :( – jay_t55 Oct 03 '09 at 00:10
1

Your regex is not the problem. Your regex as well as the one given by Wim works fine. So the problem has to be with the way the input is being handled.

Here are some things you can try:

Run this with different input, i.e. instead of using this number:

-16744193

Use something like this instead:

100
-100

Then print out the value after this line:

int fcolor = Int32.Parse(match.Groups[7].Value);

And see what it is.

Another time-saving thing you should do is print out the values in

match.Groups[1].Value
match.Groups[2].Value
match.Groups[3].Value
match.Groups[4].Value
match.Groups[5].Value
match.Groups[6].Value
match.Groups[7].Value
match.Groups[8].Value

And post them here. This will make it easy for you as well as every at SO to see what the problem is.

Vlad the Impala
  • 15,572
  • 16
  • 81
  • 124
1

Printing out the match values as suggested elsewhere would be a help, as well as shortening the regexp to make it easier to isolate the problem.

But I can suggest one more thing. Here's the last part of the regexp starting from the font size match:

..."(\d+\.\d+)\r\n(-?\d+)"

Which is supposed to match against

...
14.0
-55794414

Since you have the match for the newline immediately after the match for the font size digits, the match will fail if you have a space after 14.0. Try with

..."(\d+\.\d+)\s*\r\n(-?\d+)"

which should work both with and without trailing spaces. (Depending on your regexp engine, just "\s*" may be better than "\s*\r\n".)

There are actually a whole bunch of other things that could go wrong. It is generally easier to split up the strings and work with smaller regexps.

I suppose you already know the quote?

Some people, when confronted with a problem, think "I know, I'll use regular expressions." Now they have two problems.

j-g-faustus
  • 8,801
  • 4
  • 32
  • 42
  • thank you for the detailed answer. Personally, I've never liked Regex. But I was advised by a few people on S/O to use them. I'm trying out your advice now. Thank you :) – jay_t55 Nov 10 '09 at 11:14
  • I like regexps, they are convenient in that you can replace a page of programming with a single line. Of course, then you get one page's worth of potential bugs as well :) In practice, I have given up on regexps the size of yours, I spend too much time debugging them. In your case I would split on lines first, and have one regexp per value; it becomes more tractable that way. Good luck :) – j-g-faustus Nov 10 '09 at 11:49
0

You have only 4 groups in your regular expressions, but you are trying to access groups 5 to 8 which will be empty strings, and an empty string cannot be parsed as an integer by Int32.Parse.

Julien Lebosquain
  • 40,639
  • 8
  • 105
  • 117
0

You can use this regex:

@"(.+)\r\n""([^""]+)""\r\n(\d+),\s(\d+)\r\n([\w\s]*)\r\n(\d+\.\d+)\r\n(-?\d+)"

A usage example from which it can be seen that it works:

string value = @"Label
""this is a label""
23, 77
Tahoma
14.0
-55794414
Label
""this is a label""
23, 77
Tahoma
14.0
-55794415";

MatchCollection lines = Regex.Matches(
 value,
 @"(.+)\r\n""([^""]+)""\r\n(\d+),\s(\d+)\r\n([\w\s]*)\r\n(\d+\.\d+)\r\n(-?\d+)");
var colors = new List<int>();
foreach (Match match in lines)
{
    colors.Add(Int32.Parse(match.Groups[7].Value));
}

CollectionAssert.AreEquivalent(new[] { -55794414, -55794415}, colors);

In this example we have 2 labels with different colors, as can be seen the regex matches the colors.

The groups of the regex:

  • 0: Control
  • 1: Text
  • 2: X
  • 3: Y
  • 4: Font
  • 6: Size
  • 7: Color
Elisha
  • 23,310
  • 6
  • 60
  • 75