tags:

views:

194

answers:

2

What regular expression mechanism can be used to match "ski" but not "water ski"?

Or, match "ski" but not "ski sale"?

Could a short explanation be included?

Update: i mean, for example, it should be able to match "2009 ski competition" but not "2009 water ski competition".

+11  A: 

For the updated part, you need to use negative look-behind. Something like

(?<!water\s*)(ski\b)

That should match the word ski, where water is not the previous word.

EDIT: I tweaked the regex above, and I meant negative look-behind, not back-referencing. For ski and ski competition but but not ski sale, you need negative look-ahead. E.g.:

(\bski)(?!\s*sale)

See http://www.regular-expressions.info/lookaround.html for some more explanation.

Matthew Flaschen
Most regex engines that support lookbehind do not support variable length lookbehind, so the \s* is unlikely to work.
ysth
It works on .NET. See http://www.regular-expressions.info/refflavors.html . If the OP wants answers for a specific engine, he should say so.
Matthew Flaschen
Most regex engines that support lookbehind DO support variable length lookbehind - once there is an obvious maximum width. So a workaround to \s* is to use \s{0,100} instead (or just increase the 100 to whatever is a safe value).
Peter Boughton
A: 

You could always do a multi pass search first remove all instances of water ski and ski sale from the string then do the IsMatch on that. In C# it would look like this.

string line = Console.ReadLine();
line = Regex.Replace(line, "water ski", "");
line = Regex.Replace("ski sale", "");
bool matchFound = line.IsMatch("ski");
Jeremy E