0

This is the test. I expect the last group to be ".png", but this pattern returns "" instead.

var inputStr = @"C:\path\to\dir\[yyyy-MM-dd_HH-mm].png";
var pattern = @"(.*?)\[(.*?)\](.*?)";
var regex = new Regex(pattern);
var match = regex.Match(inputStr);

var thirdGroupValue = match.Groups[3].Value;
// ✓ EXPECTED: ".png"
// ✗ CURRENT: ""

The 1st and 2nd groups work fine.

Xavier Peña
  • 7,399
  • 9
  • 57
  • 99
  • 2
    That is because of the `?` in the last group. Your pattern there is take zero or more letters and be lazy (as in return the first part that matches). That part is just an empty string – Gilad Green Apr 08 '19 at 10:14

1 Answers1

2

This is because you made the * in Group 3 lazy:

(.*?)\[(.*?)\](.*?)
                 ^
                here

This means it will match as little as possible. What's the least .* can match? An empty string!

You can learn more about lazy vs greedy here.

You can fix this either by removing ?, making it greedy, or put a $ at the end, telling it to match until the end of the string:

(.*?)\[(.*?)\](.*)

or

(.*?)\[(.*?)\](.*?)$
Sweeper
  • 213,210
  • 22
  • 193
  • 313
  • Oh I get it. This was very informative, specially this part: `What's the least .* can match? An empty string!` <= never thought of it this way. – Xavier Peña Apr 08 '19 at 10:24