tags:

views:

602

answers:

3

I'm making a form (html & php) which is part of an admin section used to edit content for a website. I want to allow users to include some basic html. This works fine. I want to retain line breaks. This also works. My problem is that when someone writes something like this:

<ul>
<li>item one</li>
<li>item two</li>
</ul>

the line breaks between the lines of code are retained and turned into BRs when written out. This means that there's double spacing between each LI element. Now this can be fixed by writing the whole list section on one line but a) that makes it confusing to read and b) it's hard enough teaching people to use the codes let alone explaining extraineous line breaks.

What I want is some way to strip all /n out but ONLY between UL and /UL tags.

+3  A: 

This regular expression removes all linebreaks/whitespaces between <ul> and </ul> that are not part of the text between <li> and </li>

/(?<=<ul>|<\/li>)\s*?(?=<\/ul>|<li>)/is

php example:

 $output = preg_replace('/(?<=<ul>|<\/li>)\s*?(?=<\/ul>|<li>)/is', '', $input);

input:

<ul>
<li>item one</li>
<li>item two</li>
</ul>

output:

<ul><li>item one</li><li>item two</li></ul>

EDIT: fixed

port-zero
That looks perfect but It's getting an error: Warning: preg_replace() [function.preg-replace]: Unknown modifier 'l' in...I'm not too hot on regex...is there a typo there?
Mr_Chimp
tested in php5. works for me.
port-zero
Weird...I'm using PHP 5.2.9. It's a lower case L that's throwing the error. If I take the Ls out it throws an error on the < instead.
Mr_Chimp
fixed. a \ was missing
port-zero
Well I don't get an error now, but it doesn't do anything either.
Mr_Chimp
OK, I tried it out on a blank test page and it works fine...must be something elsewhere in the code throwing it off. Thanks a lot, I'll take it from here!
Mr_Chimp
A: 

You might be able to get away with using a regular expression, although this will fail if the HTML is not well formed. This should match everything within HTML tags, because the regex is greedy by default.

<?php

$str = "Hello

    <ul>
    <li>item one</li>
    <li>item two</li>
    </ul>";

$str = preg_replace_callback('~\<[^>]+\>.*\</[^>]+\>~ms','stripNewLines', $str); 

function stripNewLines($match) {
    return str_replace(array("\r", "\n"), '', $match[0]);   
}

echo nl2br($str);

Edit

Actually, this won't work. If there are two blocks of HTML with normal text in between, the text in the middle will also be stripped.

Tom Haigh
A: 

I'm having trouble understanding why line breaks are being turned into <BR>.

What's doing that? Is it the PHP?

Doesn't HTML treat a line break the same as a space? Turning them into <BR> doesn't seem right.

pavium
Line breaks are being stored as /n in the database but when they're written out on the front end I use nl2br to change them to <br>s. This makes sense most of the time. It's only a problem when using lists.
Mr_Chimp