If you have a look at what a regular expression is, you will realize that it is not possible to do flow control like loops with a regex alone. Quoting Wikipedia:
In computing, a regular expression provides a concise and flexible means to “match” (specify and recognize) strings of text, such as particular characters, words, or patterns of characters.
emphasis mine – simply put, a regex is a fancy way to find a string; it either does (it matches), or not. It is not a a set of logical processing instructions with a controllable flow – i.e. not a program.
However, there are other ways to achieve what you are after using a regex alone, as long as you use an editor that supports “Replace all” (probably a given) as well as multi-line matches and capture groups in its regex engine. Searching for
(<ul>)(<p>.*</p>)?<p>([^<])*</p>(<p>.*</p>)?(</ul>)
will match any <p></p>
block inside an <ul></ul>
block by allowing for an arbitrary number of preceding and following <p></p>
blocks, including 0 of either. Assuming your backreference syntax is $x
from your code examples, the replacement string would be
$1$2<li>$3</li>$4$5
– replace all occurences and you should be set.