I'm looking to find a regular expression that will match a list of words in any order, unless a word that is not listed is encountered. The code would be something to the sort of
// match one two and three in any order
$pattern = '/^(?=.*\bone\b)(?=.*\btwo\b)(?=.*\bthree\b).+/';
$string = 'one three';
preg_match($pattern, $string, $matches);
print_r($matches); // should match array(0 => 'one', 1 => 'three')
// match one two and three in any order
$pattern = '/^(?=.*\bone\b)(?=.*\btwo\b)(?=.*\bthree\b).+/';
$string = 'one three five';
preg_match($pattern, $string, $matches);
print_r($matches); // should not match; array()
Maybe you can try this:
$pattern = '/\G\s*\b(one|two|three)\b(?=(?:\s\b(?:one|two|three)\b)*$)/';
$string = 'one three two';
preg_match_all($pattern, $string, $matches);
print_r($matches[1]);
\G
resets the matching after each match.
Output:
Array
(
[0] => one
[1] => three
[2] => two
)
You should be able to do this without the need for look ahead.
Try a pattern like
^(one|two|three|\s)+?$
the above will match one
, two
, three
, or a \s
white space character.
Try with this:
$pattern = '/^(?:\s*\b(?:one|two|three)\b)+$/';
If it is required to have all of 'one, two, three'
and there not be a different word this works.
# ^(?!.*\b[a-zA-Z]+\b(?<!\bone)(?<!\btwo)(?<!\bthree))(?=.*\bone\b)(?=.*\btwo\b)(?=.*\bthree\b)
^
(?!
.* \b [a-zA-Z]+ \b
(?<! \b one )
(?<! \b two )
(?<! \b three )
)
(?= .* \b one \b )
(?= .* \b two \b )
(?= .* \b three \b )