$str = preg_replace('~(*BSR_ANYCRLF)\R(\R?)~', '$1', $str);
\R
с параметром (*BSR_ANYCRLF)
соответствует любой последовательности новой строки типа CRLF (удалите эту опцию, чтобы соответствовать всем новым строкам Юникода).
\R(\R)?
приведет к $1 = '\R'
с двумя символами новой строки и $1 = ''
с одним символом новой строки.
Приведенный выше текст полностью пропустит символ новой строки, если у вас есть только один. Это, вероятно, не то, что вы хотите. Вместо этого я бы предложил оставить одиночные символы новой строки в одиночестве и преобразовать двойные символы новой строки в теги HTML <br />
:
$str = preg_replace('~(*BSR_ANYCRLF)\R{2}~', '<br />', $str);