well, I'm not sure if you correctly copy/pasted your example string, but there is an extra character between each occurence of the \r\n
string, so basically the following regex:
re.sub(r'(\r\n.?)+', r'\r\n', text)
will remove any of:
\r\n\r\n
\r\n \r\n
\r\n\n\r\n
\r\n\r\n\r\n
\r\n \r\n \r\n
\r\n\r\n \r\n
\r\n \r\n\r\n
...
full test:
>>> text = """<ul>\r\n \r\n <li><a href="#">link</a></li>\r\n \r\n <li><a href="#">link</a></li>\r\n <li><a href="#">link</a></li>\r\n \r\n <li><a href="#">link</a></li>\r\n \r\n </ul>\r\n"""
>>> print text
<ul>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
</ul>
>>> print re.sub(r'(\r\n.?)+', r'\r\n', text).__repr__()
'<ul>\r\n<li><a href="#">link</a></li>\r\n<li><a href="#">link</a></li>\r\n<li><a href="#">link</a></li>\r\n<li><a href="#">link</a></li>\r\n</ul>\r\n'
>>> print re.sub(r'(\r\n.?)+', r'\r\n', text)
<ul>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
<li><a href="#">link</a></li>
</ul>
N.B.:
the following regexp:
print re.sub(r'([\r\n]+.?)+', r'\r\n', text)
works as well, and can support \n
only strings.
HTH