Исправление регулярного выражения
Это регулярное выражение работает:
(\s*<li>.*?<\/li>\s*)(?!\s*<li>)
Объяснение:
.*?
просит регулярное выражение:как можно меньше совпадать между <li>
и </li>
, чтобы оно прекратилось, как только будет текст, не входящий в <li>
; - Я избежал
/
во втором случае </li>
, как вы уже сделали в первом случае; (?!\s*<li>)
говорит, что следующий бит текста не может быть другим <li>
- необходим, потому что в противном случае .*?
выше делает его соответствующим каждой строке <li>
отдельно; - первоначальный
(?!<\/li>)
на самом деле ничего не делает, поэтому я удалил его.
Более удобная обработка новых строк
Вкл.на веб-сайте Live Regex я не смог вставить новые строки там, где хотел.
В самом php вы можете использовать
preg_replace('/\s*(<li>.*?<\/li>)\s*(?!\s*<li>)/smi',
"\n<ul>\n$1\n</ul>\n", $input)
или
preg_replace('/(\s*<li>.*?<\/li>\s*)(?!\s*<li>)/smi',
"\n<ul>$1</ul>\n", $input)
чтобы получить более хорошие результаты.Ключ заключается в том, чтобы поместить шаблон замены в двойные кавычки.
Лучшая обработка ввода с отступом
Если ввод был с отступом, вы также можете рассмотреть что-то вроде этого:
preg_replace('(\s*)(<li>.*?<\/li>)(\s*)(?!\s*<li>)/smi',
"$1<ul>$1$2$1</ul>$3", $input)
это установит <ul>
и </ul>
на тот же уровень отступа, что и первый <li>
, и сохранит окружающий текст на том же отступе, что и раньше.
Но, очевидно, ни одинэто действительно важно, учитывая, что все эти интервалы не изменят интерпретацию получающегося HTML.