preg_match_all(
'/\d # match a digit
(?=.*def) # only if followed by <anything> + def
(?!.*abc) # and not followed by <anything> + abc
/x',
$subject, $result, PREG_PATTERN_ORDER);
$result = $result[0];
работает на вашем примере. Предполагается, что в вашей строке ровно один экземпляр abc
и def
на строку.
Причина, по которой ваша попытка не сработала, заключается в том, что ваша группа захвата (\d)
, соответствующая цифре, находится в другой повторяющейся группе (?:a(\d)a)+
. При каждом повторении результат захвата перезаписывается. Так работают регулярные выражения.
Другими словами - посмотрите, что происходит во время матча:
Current position Current part of regex Capturing group 1
--------------------------------------------------------------
a1a no match, advancing... undefined
abc abc undefined
a2a (?:a(\d)a) 2
a3a (?:a(\d)a) (repeated) 3 (overwrites 2)
def def 3