You can use an atomic group:
(?<!\bla\s+(?:petite\s+)?)(?:petite\s+)?(?>maison(?:e?s|x)?\b(?:\s+bleu[sxe]?)?)(?!\s+ciel)
See the .NET regex demo.
Details
(?<!\bla\s+(?:petite\s+)?)
– a location in string not immediately preceded with a whole wordla
(\b
is a word boundary) followed with 1+ whitespaces and an optional sequence ofpetite
and 1+ whitespaces(?:petite\s+)?
– an optionalpetite
and 1+ whitespaces sequence(?>maison(?:e?s|x)?\b(?:\s+bleu[sxe]?)?)
– here, an atomic group that matchesmaison
, then an optional sequence of an optionale
followed withs
or anx
, then a word boundary and then an optional sequence of 1+ whitespaces andbleu
followed with 1 or 0s
,x
ore
(?!\s+ciel)
– not followed with 1+ whitespaces andciel
.
See the C# demo:
var rx = @"(?<!\bla\s+(?:petite\s+)?)(?:petite\s+)?(?>maison(?:e?s|x)?\b(?:\s+bleu[sxe]?)?)(?!\s+ciel)";
var strings = new List<String> {" - maison"," - petite maison"," - maison bleue",
" - petite maison bleue"," - la maison"," - maison ciel"," - la petite maison",
" - maison bleue ciel"," - la petite maison bleue"," - petite maison bleue ciel",
" - la maison bleue ciel"," - la petite maison ciel"," - la maison ciel"," - la petite maison bleue ciel"};
foreach (var s in strings)
{
Console.WriteLine("{0} => \"{1}\"", s, Regex.Match(s, rx)?.Value);
}
Output:
- maison => "maison"
- petite maison => "petite maison"
- maison bleue => "maison bleue"
- petite maison bleue => "petite maison bleue"
- la maison => ""
- maison ciel => ""
- la petite maison => ""
- maison bleue ciel => ""
- la petite maison bleue => ""
- petite maison bleue ciel => ""
- la maison bleue ciel => ""
- la petite maison ciel => ""
- la maison ciel => ""
- la petite maison bleue ciel => ""
CLICK HERE to find out more related problems solutions.