Это должно работать:
preg_match_all('#http://www.amazon.com/([\w-]+/)?(dp|gp/product)/(\w+/)?(\w{10})#', $data, $matches);
Когда вы используете конструктор JavaScript RegExp
со строкой, все обратные косые черты должны быть экранированы другой обратной косой чертой. Это не так с PHP.
И обычно вы бы использовали /
в качестве разделителя для регулярного выражения, но так как в этом случае у вас много /
в строке поиска, разумнее использовать какой-либо другой разделитель, поэтому вам не нужно избежать каждого слэша с помощью обратного слэша. В этом случае я использовал знак фунта в качестве разделителя.