0

Im trying to detect newlines in PHP and replace them with <br> which are not preceded by </ul>, <ul>or </li>.

te
<ul>
<li>iasd</li>
<li>asd</li>
</ul>
ja
123

should result in

te<br>
<ul>
<li>iasd</li>
<li>asd</li>
</ul>
ja<br>
123<br>

The Regex I came up with so far (^|^.|.[^((\/li>)|<\/ul>|<ul>)])\r?\n works, but also is triggered when there only is a > in front of the new line.

Jonathan Leffler
  • 730,956
  • 141
  • 904
  • 1,278
Chris
  • 4,255
  • 7
  • 42
  • 83
  • https://stackoverflow.com/questions/1732348/regex-match-open-tags-except-xhtml-self-contained-tags – Lord Elrond Feb 28 '20 at 05:56
  • There wont be any title or class attributes in those elements so I don't think those answers affect me? I have total controll over the HTML – Chris Feb 28 '20 at 06:03
  • You missed the point of the post. You shouldn't use regex for this. Instead I would parse the data as HTML, then determine where you want to insert `
    `
    – Lord Elrond Feb 28 '20 at 06:07
  • So, what you mean to say is that you treat the HTML as plain text and the only "HTML" is substrings between `<` and `>` that have no `<` and `>` inside them, right? Pleae add this information to the question then. – Wiktor Stribiżew Feb 28 '20 at 08:09
  • Try `preg_replace('~
      [^<]*(?:<(?!/?ul>)[^<]*)*
    \s*(*SKIP)(*F)|$~sm', '
    ', $text)`, see https://3v4l.org/2JnT2
    – Wiktor Stribiżew Feb 28 '20 at 08:42

1 Answers1

0

How about replacing:

(?<!(?:<ul>)|(?:<\/ul>)|(?:<\/li>))([\n\r]|$)

With <br>\1

As seen here

Explanation:

Using negative lookbehinds and well, lookbehinds in general makes your life much easier. You can learn more abour there here: https://www.regular-expressions.info/lookaround.html

Community
  • 1
  • 1
Robo Mop
  • 3,485
  • 1
  • 10
  • 23