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
  • 6,033
  • 7
  • 49
  • 91
  • 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
  • 145,870
  • 17
  • 129
  • 225
  • 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