Since you're in multiline mode, you could match on line endings to delineate each line.
This matches two lines and replaces them with the first line only (effectively removing the second line). Notice I've removed "dotall" mode (s
).
$regex = '/(^#EXTINF:\d+,$)(\s+)^.+$(?=\s+^#EXT)/m';
echo preg_replace($regex, '$1', $str);
Output:
#EXTM3U
#EXT-X-TARGETDURATION:10
#EXTINF:10,
#EXTINF:5,
#EXT-X-ENDLIST
Update:
Using a lookbehind will not work, as it requires variable-length matching, which is unsupported in most regex engines (including PCRE, which PHP uses).
If you want to capture only the line you want to remove and not have to replace two lines with a subpattern match like I did above, you can use the \K
escape sequence to simulate a lookbehind that is not subject to variable-length restrictions. \K
resets the match's start position, so anything that was matched before the \K
will not be included in the final match. (See the last paragraph here.)
$regex = '/^#EXTINF:\d+,\s+\K^.+?(?=#EXT)/sm';
echo preg_replace($regex, '', $str);