I think it's vaguely explained here.

I believe what is happening is that it finds a space (\s), then repeats the '.' as few times as it can before finding a '%'. Which isn't the same as it finding the fewest characters to the left of the % before encountering a space (which is what you are expecting, I believe).

I guess one alternative that does what (I think) you want is:
Code:
/\s(\S*?%\S*?)\s/

or
Code:
/\b(\S*?%\S*?)\b/