I suggest you use binding \Gto do continuous string matching.
(?:<img|(?<!^)\G)\h*([\w-]+)="([^"]*)"(?=.*?\/>)
Get the attribute from the index of group 1 and get the value from the index of group 2.
Demo
$string = <<<EOT
<img src="abc.png" alt="abc" />
<img alt="def" src="def.png" />
<img src="abc.png" alt="abc" style="border:none" />
<img alt="def" src="def.png" style="border:none" />
EOT;
preg_match_all('~(?:<img|(?<!^)\G)\h*(\w+)="([^"]+)"(?=.*?\/>)~', $string, $match);
print_r($match[1]);
print_r($match[2]);
Conclusion:
Array
(
[0] => src
[1] => alt
[2] => alt
[3] => src
[4] => src
[5] => alt
[6] => style
[7] => alt
[8] => src
[9] => style
)
Array
(
[0] => abc.png
[1] => abc
[2] => def
[3] => def.png
[4] => abc.png
[5] => abc
[6] => border:none
[7] => def
[8] => def.png
[9] => border:none
)
source
share