The string I am using as my subject is:
‘Save 68% on a 4 Day/3 Night vacation at. Only $249!’
I’m using '.\*(\b((enjoy|save)( up to| an extra)?|starting at|as low as|just|only)\b ([0-9]{1,3} ?\%|\$[0-9]+(\.[0-9]{2})?)).\*/i' to try to match a part of the above string a extract it.
I’m using '$1' as the replacement, so my full preg_match looks like
preg_match('.*(\b((enjoy|save)( up to| an extra)?|starting at|as low as|just|only)\b ([0-9]{1,3} ?\%|\$[0-9]+(\.[0-9]{2})?)).*/i', '$1', 'Save 68% on a 4 Day/3 Night vacation at. Only $249!')
It should match 'Save 68%' first but it keeps returning 'Only $249'.
I’ve found that if I add a question mark after the first wildcard '.\*?(\b((enjoy|save)( up to| an extra)?|starting at|as low as|just|only)\b ([0-9]{1,3} ?\%|\$[0-9]+(\.[0-9]{2})?)).\*/i' it does return 'save 68%'. Is there another way around this. It seems to have to do with my grouping. As I’ve found that
preg_match('/.*\b(enjoy|save)( up to| an extra)?|starting at|as low as|just|only\b.*/i', '$1', 'Save 68% on a 4 Day/3 Night vacation at. Only $249!')
returns 'save' like it should, but I can’t get the same thing to work on the full statement.
The reason why adding a question mark after the first wildcard works, is that
.*is greedy, and the question mark (.*?) makes it lazy. A greedy operator will match as much as possible, which in your case is the whole line (.*says “match anything as many times as possible”). Making it lazy will cause it to match as little as possible. Read more about this in the repetition section of the PCRE manual pages.For your particular problem, what’s wrong with using the lazy operator? If it results in what you want, I say go with it.