5

How to get the lookbehind to be greedy?
In this case I want the lookbehind to consume the : if is is present.

m = Regex.Match("From: John", @"(?i)(?<=from:)....");
// returns ' Jon' what I expect not a problem just an example

m = Regex.Match("From: John", @"(?i)(?<=from:?)....");
// returns ': Jo'
// I want it to return ' Jon'

I found a work around

@"(?i)(?<=\bsubject:?\s+).*?(?=\s*\r?$)"

As long as you put some affirmative after the ? then it takes the optional greedy out of play. For the same reason I had to put the $ in the look forward.
But if you need to end on an optional greedy then have to go with the accepted answer below.

paparazzo
  • 44,497
  • 23
  • 105
  • 176

1 Answers1

4

Interesting, I didn't realise they were non-greedy in .NET. Here is one solution:

(?<=from(:|(?!:)))

This means:

(
  :     # match a ':'
  |
  (?!:) # otherwise match nothing (only if the next character isn't a ':')
) 

This forces it to match the ':' if present.

porges
  • 30,133
  • 4
  • 83
  • 114
  • Little verbose but it works and that works for me. Thanks. I consider it a bug that the lookbehind is not greedy. – paparazzo Sep 04 '12 at 23:58
  • @Blam: Just realized this can be simplified to be less verbose. I updated my post. – porges Sep 06 '12 at 09:54
  • No that fails the compiler please fix or go back to original answer rSubject = new Regex(@"(?i)(?<=subject(:|(?!:)))........)"); – paparazzo Sep 06 '12 at 13:30
  • @Blam: There's a typo in your example - the last ')' shouldn't be there. `new Regex(@"(?i)(?<=subject(:|(?!:)))........")` – porges Sep 06 '12 at 21:52
  • Thanks that seems to work. I already gave you a +1 so I can't do it again. Regex is cool but not very forgiving. – paparazzo Sep 07 '12 at 01:47