I’m not a regex pro neither so we speak the same language.
Did you use the s modifier when you tested both regex?
My understanding is that with the s modifier turned on the first regex will match the whole string :
<img width="155" height="300" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-src="https://local.wordpress.dev/wp-content/uploads/2013/03/featured-image-vertical-155x300.jpg" class="attachment-medium wp-post-image" alt="Horizontal Featured Image" /><noscript><img width="155" height="300" src="https://local.wordpress.dev/wp-content/uploads/2013/03/featured-image-vertical-155x300.jpg" class="attachment-medium wp-post-image" alt="Horizontal Featured Image" /></noscript>
<img class="fl-photo-img" src="https://local.wordpress.dev/wp-content/uploads/2015/04/5527cc7c08d02_input_1.jpg" alt="5527cc7c08d02_input_1" itemprop="image" />
Indeed if we split the regex: <img[\s\r\n]+.*?\/>(?!<noscript>|<\/noscript>)
<img[\s\r\n]+
will match opening img tag followed by one or more white space, carriage return or new line.
.*?
match any character (new line included with the s modifier turned on), zero or more times.
\/>(?!<noscript>|<\/noscript>)
match the ending tag if not followed by <noscript> or </noscript>.
So this regex will not match :
<img width="155" height="300" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-src="https://local.wordpress.dev/wp-content/uploads/2013/03/featured-image-vertical-155x300.jpg" class="attachment-medium wp-post-image" alt="Horizontal Featured Image" /><noscript>
as the ending img tag is followed by <noscript>.
However it will match the whole string matching the first opening img tag and everything that stands between it (without any restriction with .*?) and the first closing tag that is not followed by <noscript> or </noscript> so the closing tag of the second img in our example :
<img width="155" height="300" src="data:image/gif;base64,R0lGODlhAQABAIAAAAAAAP///yH5BAEAAAAALAAAAAABAAEAAAIBRAA7" data-src="https://local.wordpress.dev/wp-content/uploads/2013/03/featured-image-vertical-155x300.jpg" class="attachment-medium wp-post-image" alt="Horizontal Featured Image" /><noscript><img width="155" height="300" src="https://local.wordpress.dev/wp-content/uploads/2013/03/featured-image-vertical-155x300.jpg" class="attachment-medium wp-post-image" alt="Horizontal Featured Image" /></noscript>
<img class="fl-photo-img" src="https://local.wordpress.dev/wp-content/uploads/2015/04/5527cc7c08d02_input_1.jpg" alt="5527cc7c08d02_input_1" itemprop="image" />
Now if we replace .*? by ([^<]+) we still match everything except a new opening tag and so it prevent the regex to spread accross multiple tags.
So the resulting regex should be:
<img[\s\r\n]+([^<]+)\/>(?!<noscript>|<\/noscript>)
With this you can even remove the s modifier as negative class always match new line character (see https://php.net/manual/en/reference.pcre.pattern.modifiers.php).
You’ll also noticed that I added back the + after [\s\r\n] that was missing in my previous version.
What do you think?