views:

355

answers:

3

I've gone over other questions from stack overflow with similar ideas but none seem to resemble closely enough what I'm trying to do.

Seems simple, but I'm in a pickle. I'm trying to replace multiple occurrences of a line break (\n) with only one line break, so people won't be able to submit more than one line break at a time. Here's what I've tried.

$text = "Foo\n\n\nbar!\n\nfoobar!";
$text = preg_replace("#\n+#", "\n", $text);
echo $text;

The expected returned statement would be:

Foo\nbar!\nfoobar!

But no cigar! I tried several but none seemed to work.

What am I doing wrong?

Thanks!

+1  A: 

You might also want to check for all three varieties of line breaks:

$text = "Foo\n\r\n\n\rbar!\n\nfoobar!";
$text = preg_replace('#(\r\n|\r|\n)+#m', "\n", $text);
echo $text;
Max Shawabkeh
still no cigar... I paid close attention to the the single quotes you used and the 'm' but it doesn't seem to work
yuval
`m` is not needed.
Bart Kiers
@Bart: yes, and neither are the single quotes, though neither matter. The point of my post was the support of Windows/UNIX/Mac line breaks.
Max Shawabkeh
+1  A: 
$text = "Foo\n\n\nbar!\n\nfoobar!";
$s = split("\n+",$text);
print_r( implode("\n",$s)); #this will join the string with newline
print_r( implode("\\n",$s)); # this will have literal \n in your string 
ghostdog74
tried this out as well, does not seem to work. I should mention I'm getting my data from a textarea. It's possible my input doesn't contain \n but a different char, I suppose, but I tried echoing it out and it certainly does not look that way
yuval
A: 

If you're only interested in the solution, skip to the last line.

Here's what ended up happening. I had a div tag in html that contained certain information. When a user hits a button, a JS code runs that converts that div to an input textbox, and sets the value of that textbox as the html of the original div - while replacing all occurrences of <br> with \n to create real line breaks. The form then got submitted via ajax to the server.

When I tried to replace the line breaks in PHP, none of the above suggestions helped, for the simple reason that it wasn't (curiously enough) a "real" linebreak character. What got submitted to the server was the literal \n. You'd think escaping the backslash in \n, as suggested by ghostdog74 would solve the problem but it did not. I tried escaping it several different ways but nothing seemed to help.

I ended up referencing some old regex material and found that:

Many flavors also support the \Q...\E escape sequence. All the characters between the \Q and the \E are interpreted as literal characters. E.g. \Q*\d+*\E matches the literal text \d+. The \E may be omitted at the end of the regex... This syntax is supported by the JGsoft engine, Perl, PCRE... [source]

Following that, here's the piece of code that solved my problem:

$text = preg_replace('#[\Q\n\E]+#', "\n", $text);

Thank you everybody for all your help! +1 for all :)

yuval
That will replace any backslashes and "n" letters in the input since everything is inside a character class - those should be normal rather than square brackets. Also, using single quotes and triple-escapes (`pattern = '#(\\\n)+#';`) would work correctly in this case too, but it is admittedly ugly.
Max Shawabkeh