3

I'm having some problems with a "bb parser" I'm coding. Or, well, not with the parser itself, but the nl2br modifying it.

The string from the database is like the following:

text text text

[code]code code code[/code]

text text text

Now, nl2br puts one br / after the first "text text text", and then another one below that, so there's two line breaks before the [code] tag (which actually is correct, but not what I want).

Is there any way I can limit how many br's are entered in a row? I can't seem to find a solution that's simple enough.

Thanks in advance, guys.

Fredrik
  • 31
  • 2
  • so what your really asking is how to find 2 new line characters and replace with one? –  May 14 '11 at 10:11
  • Well, yeah :) And to limit all additional line breaks to only show the first one, ignoring user's inputs if they're wrong for the tempate. – Fredrik May 14 '11 at 10:46

3 Answers3

4

In addition to previous solution, I add a different one, since Fredrik asked for it. This will replace double <br> after nl2br instead of before.

$string = nl2br( $string );
$string = preg_replace( '/(<br(?: \\/)?>\\r?\\n?\\r?)(?=\\1)/is', '', $string );
AndersTornkvist
  • 2,610
  • 20
  • 38
  • Huge thanks for your effort, unfortunately I can't get it to work. I think the problem is that the
    s are on separate lines, each on a new line, when they're in a row. What do you think?
    – Fredrik May 15 '11 at 06:03
  • 1
    @Fredrik Thank you. It works with: `$string = "This is row 1\nThis is row 2\n\nRow 4 after empty row 3\n\n\n\n\n\nRow 10 after some empty rows"; $string = nl2br( $string ); echo $string; // with multiple
    in a row $string = preg_replace( '/(
    \\n?)(?=\\1)/is', '', $string ); // with no more than one
    in a row echo "
    " . $string;` `\\n?` matches a linebreak, so that shouldn't be a problem. Do you have an example echo `htmlspecialchars($string)` after `nl2br()`? I think that will help us solve it.
    – AndersTornkvist May 15 '11 at 07:30
  • The problem could be different linebreaks than `\n`. I've updated the regex therefore. Does it fit now? – AndersTornkvist May 15 '11 at 07:38
  • @Richard86 @Fredrik this solution as it is would actually remove any even number of
    's and not restrict them to one -- in fact you'll end up with none about half the time. To make it one, you'd have to replace with a single
    instead of the empty string, and perhaps put it into a do-while loop until there are no longer matches. It's not very efficient for large strings, but would do the trick.
    – sakatc May 15 '11 at 07:48
  • 1
    @sakatc I'm not sure I understand how you concluded this. Let me explain the regex. The first part `(
    \\r?\\n?\\r?)` checks for `
    /
    ` and a line break if it exists. The second part `(?=\\1)` matches the same `
    /
    ` again, but is preceeded by `?=`. Therefore, it will make any number greater than 1 `
    /
    ` to one single `
    /
    `, both even and odd numbers. This is because the regex only deletes the first `
    /
    ` (i.e., thanks to `?=`) and moves the internal pointer to next `
    /
    `. Have you tried the regex at all, @sakatc?
    – AndersTornkvist May 15 '11 at 08:01
  • @Richard86 ah sorry about that! missed the ?= and perhaps read it as a ?: ... makes sense to me now. ;D – sakatc May 15 '11 at 08:07
  • @sakatc Don't worry! It is easy to miss that. – AndersTornkvist May 15 '11 at 08:09
  • @Richard86, oh sorry, yes there is actually a htmlspecialchars() in the parser script, before nl2br. Does that change how the script should look? – Fredrik May 15 '11 at 09:08
  • @Fredrik No, it won't matter to the regex. I would just like to see how one of your example `$string`s actually look before `preg_replace()`. – AndersTornkvist May 15 '11 at 10:35
  • The string itself is just plain text from a mysql entry, no \r or \n. Ser förresten nu att du är svensk, kan du maila mig direkt istället? förnamn + lagnetoft snabel-a me punkt com :) – Fredrik May 15 '11 at 11:57
  • @Fredrik Okey, I think you need to show us exactly what the string looks like. (Jag skickade men fick aldrig något svar;)) – AndersTornkvist May 23 '11 at 07:32
  • @Richard86: Hmm, har inte fått något mail. Nåja! – Fredrik Aug 16 '11 at 07:58
  • To everyone: The problem seems to be fixed once I added mysql_real_escape_string before getting the string from the database. Didn't know I had to do that when taking something out, well, now the function works! Now I'm just wondering how to allow TWO line breaks instead of just one. :) – Fredrik Aug 16 '11 at 07:59
  • To allow single or double line breaks, you should be able to use `\\1\\1` instead of `\\1`. This would make sure there are at least two line breaks after the first one before deleting. – AndersTornkvist Aug 22 '11 at 12:31
0

You could for example replace two linebreaks (or more) by one by using preg_replace :-)

tim
  • 9,896
  • 20
  • 81
  • 137
  • Thanks for the reply! However I can't seem to get it to work as the
    s are created on separate rows. Do you know how to do that?
    – Fredrik May 14 '11 at 10:43
0

You could use

$string = str_replace(array("\r\n\r\n", "\n\r\n\r", "\n\n", "\r\r"), array("\r\n","\n\r","\n","\r"), $string);

This prevents double <br> tags. Preg_replace as suggested before is better if there could be more than two new lines in a row.

AndersTornkvist
  • 2,610
  • 20
  • 38
  • Thanks! I'm looking into the preg_replace solution, but as I commented on that solution I can't get it to work as they're on separate rows after nl2br has modified the string. – Fredrik May 14 '11 at 10:45
  • @Fredrik You're welcome! I added a new solution to allow you to modify the string after nl2br. Please see if it fits your purpose. – AndersTornkvist May 14 '11 at 15:46