tags:

views:

132

answers:

3

(in PHP ... ) I'm trying to take a block of text and remove all hard line breaks so it can be re-wrapped to a specific line length using wordwrap().

However, since its possible to have multiple paragraphs, I'm assuming I need a way to remove a single newline, but not two in a row.

If this is right, how can I say find \n but not \n\n in a regular expression? Or am I approaching this the wrong way?

+2  A: 

Try:

preg_replace('!(?<!\n)\n(?!\n)!', '', $input);

See Lookahead and Lookbehind Zero-Width Assertions for how this works.

This removes any newlines that aren't preceded or followed by a newline. You have to do both otherwise if you have this combo:

This is some text\n\n

then the first won't match (newline not followed by newline) as it is followed by a newline but the second will because it isn't followed by a newline (but it is preceded by one).

Alternatively you could do:

preg_replace_callback('!\n+!', 'replace_newline', $input);

function replace_newline($matches) {
  return strlen($matches[0]) == 1 ? '' : $matches[0];
}

Also I've assumed you do just mean newlines and not \r as well. Either solution can be adjusted for this.

cletus
+1 for a correct solution.
Dan McGrath
Modified it to handle \r\n since its being fed text from a HTML textarea. Thanks for this.
Erik
A: 

Not sure this is the best solution but couldn't you just use a regex to look for the \n\n first - replace it with something (e.g. <br>) - and then look for \n?

malonso
That would fail if your text also contained <br>.
Mark Byers
Ahh, good call Mark. Sorry, I didn't explicitly mean to use that but rather to insert whatever they preferred. Nice catch.
malonso
+1  A: 

I see you've already accepted an answer but I thought I'd toss this out:

preg_replace("|\n{1}|", "");

This basically says 'replace all instance of "1 and only 1 new lines" with "a space"'.

This is more of a guess as I've not tried it out. But "limit" with no min is supposed to match absolutely.

ChronoFish