Как обнаружить второе появление с помощью регулярного выражения? (РНР)

Из этого вопроса Как сопоставить это с помощью регулярного выражения

Прямо сейчас я хочу найти ключевое слово 3D D из представленных пользователем данных. Правило до тех пор, пока в предложении присутствуют 3D и D, он действителен (нечувствителен к регистру).

Например:

3Dzzzzzzzzzzzzzzzzzzz (недействителен, поскольку нет второго появления D)
zzzzzD (неверно, потому что нет 3D)
xxx3DzzzzzD (действительный, поскольку получил 3D и D в строке)

Я использую это регулярное выражение сейчас, но почему-то у него есть одна проблема.

$subject = 'BLASHSH*3D*8qw9e08e2323*D*'; if(preg_match('/(?=.*3D)(?=.*D).*/i', $subject)) { echo 'pattern match'; } else { echo 'fail'; } 

Проблема в том, что эта строка также вернет true

3D (он должен быть недействительным, поскольку второе вхождение D)
3D ABC (он должен быть недействительным, потому что второе вхождение D)

Как это решить?

Предполагая, что 3DD , D3D и cccDzzz3D действительны:

 /(3D.*D)|(D.*3D)/i 

И так как вы использовали модификатор i , прежде чем я предполагаю, что вы хотите принять 3d и d ? Если не просто удалить i из конца регулярного выражения.

Если правило заключается в том, что 3D должен появиться перед D и может иметь любое количество символов до, после или между ними (включая нулевые символы), этого должно быть достаточно:

 /3D.*D/i