in reply to regex exercise

/m isn't needed, as you don't use ^ or $ in the regex. /i isn't needed, either, as <p> is always lowercase in the sample data.

I also used s%%% instead of s/// to avoid the need to backslash the slashes in endtags.

s%(<p>(?=(?:(?!</p>).)*\n\n)(?:(?!</p>).)*</p>)%-->$1<--%sg

Explanation:

The p-tag must be followed by two newlines that aren't preceded by its endtag.

You can make the regex more readable via /x :

s{ (<p> (?=(?:(?!</p>).)*\n\n) # Followed by two newlines not precede +d by </p> (?:(?!</p>).)*</p>) # Followed by </p> not preceded by </p +> }{-->$1<--}sgx;

Update: or even

my $not_followed_by_end_p = qr{(?:(?!</p>).)*}s; while (<>) { s{ (<p> (?=$not_followed_by_end_p\n\n) $not_followed_by_end_p</p>) }{-->$1<--}gx; print; }

($q=q:Sq=~/;[c](.)(.)/;chr(-||-|5+lengthSq)`"S|oS2"`map{chr |+ord }map{substrSq`S_+|`|}3E|-|`7**2-3:)=~y+S|`+$1,++print+eval$q,q,a,