Til: Absätze formatieren

Moin!

Ich möchte Texte aus einer Datenbank formatieren.
Aus so einem Text:

Das ist ein Absatz.

Das ist auch ein Absatz.

Und das ist noch einer.

Soll das hier werden:

<p>Das ist ein Absatz.</p>
   <p>Das ist auch ein Absatz.</p>
   <p>Und das ist noch einer.</p>

Ich dachte, das geht ganz einfach so:

$text = '<p>' . $text . '</p>';
   $text = str_replace("\n\n","</p><p>",$text);

...tut es aber nicht! :-( Die doppelten Zeilenumbrüche werden nicht erkannt. Was stimmt da nicht?
Und unabhängig davon: wäre hier ein regulärer Ausdruck sinnvoller?

Danke!
Til

  1. Hallo Til,

    Es gibt das beruehmte CK Posting im PHP Manual, das deine Frage so beantworten wuerde
    $text = preg_replace("/(\015\012)|(\015)|(\012)/","</p><p>",$text);
    Evtl. musst du den Ausdruck noch mit einem Quantifier versehen.

    Gruß,

    Dieter

    1. Hallo Dieter,

      Es gibt das beruehmte CK Posting im PHP Manual, das deine Frage so beantworten wuerde

      Ah, Zeilenumbrüche sind plattformabhängig - schon wieder was gelernt!

      $text = preg_replace("/(\015\012)|(\015)|(\012)/","</p><p>",$text);

      Ja, das funktioniert schon mal ganz gut!

      Evtl. musst du den Ausdruck noch mit einem Quantifier versehen.

      Du meinst, dass auch nur doppelte Zeilenumbrüche ersetzt werden, oder?

      Til

      1. Hallo Til,

        Du meinst, dass auch nur doppelte Zeilenumbrüche ersetzt werden, oder?

        Ja, so ersetzt der Ausdruck ja nur einfache Umbrueche. Es sollte funktionierer, wenn du den ganzen Ausdruck klammerst und {2} dahinter setzt, also
        "/(Ausdruck){2}/"

        anstatt
        "/Ausdruck/"

        Gruß,

        Dieter

        1. Hallo Dieter,

          Ja, so ersetzt der Ausdruck ja nur einfache Umbrueche. Es sollte funktionierer, wenn du den ganzen Ausdruck klammerst und {2} dahinter setzt, also
          "/(Ausdruck){2}/"

          Hm, komischerweise wird damit ein einzelner Zeilenumbruch auch ersetzt. Mit $text = preg_replace("/((\015\012)|(\015)|(\012)){3}/","</p><p>",$text); scheint es aber zu gehen.

          Til

          1. Hallo Til,

            Hm, komischerweise wird damit ein einzelner Zeilenumbruch auch ersetzt. Mit $text = preg_replace("/((\015\012)|(\015)|(\012)){3}/","</p><p>",$text); scheint es aber zu gehen.

            Kann schon sein, ich hab das nicht weiter getetstet.

            Gruß,

            Dieter

            1. ...nochmal hallo,

              Hm, komischerweise wird damit ein einzelner Zeilenumbruch auch ersetzt. Mit $text = preg_replace("/((\015\012)|(\015)|(\012)){3}/","</p><p>",$text); scheint es aber zu gehen.
              Kann schon sein, ich hab das nicht weiter getetstet.

              Naja, auf jedenfall geht's so:
              $text = preg_replace("/(\015\012\015\012)|(\015\015)|(\012\012)/","</p><p>",$text);

              Gruß
              Til

  2. Und unabhängig davon: wäre hier ein regulärer Ausdruck sinnvoller?

    Immer wenn Du etwas auch mit String-Funktionen erledigen kannst, dann nimm keinen regulären Ausdruck.
    Reguläre Ausdrücke können alles und sind alles - nur eben nicht schnell.
    Teste mal die Zeit, die eine Erstetzung mit String-Funktionen und mit RegEx dauert. Das ist tatsächlich ein erheblicher Unterschied.

    Gruß, rob

    1. Hallo rob,

      Immer wenn Du etwas auch mit String-Funktionen erledigen kannst, dann nimm keinen regulären Ausdruck.

      Zustimmung

      Teste mal die Zeit, die eine Erstetzung mit String-Funktionen und mit RegEx dauert. Das ist tatsächlich ein erheblicher Unterschied.

      Das Problem ist, dass die verschiedenen \r\n Moeglichkeiten betriebssystemabhaengig sind, also scheint ein regulaerer Ausdruck hier angebracht. Das auch insbesondere im Hinblick darauf, dass haeufig unter Windows entwickelt wird und die fertige Seite unter Linux laeuft.
      Wenn man zB. preg_replace vs. str_replace in Maßen benutzt, sind die Unterschiede kaum spuerbar, jedenfalls reichen sie nicht, um sich noch schnell einen Kaffee zu besorgen ;-)

      Gruß,

      Dieter

      1. Moin,

        Das Problem ist, dass die verschiedenen \r\n Moeglichkeiten betriebssystemabhaengig sind, [...]

        Wie wär's damit?

        // ert mal alles in ein <p></p>:
           $text = '<p>' . $text . '</p>';

        // doppelte Zeilenumbrüche in Absätze umwandeln:
           // Linux:
           $text = str_replace("\n\n","</p><p>",$text);
           // Windows:
           $text = str_replace("\r\n\r\n","</p><p>",$text);
           // Mac:
           $text = str_replace("\r\r","</p><p>",$text);

        // einfache Zeilenumbrüche in <br /> umwandeln:
           $text = nl2br($text);

        Gruß
        Til

        1. Hallo Til,

          Ich zitiere mal aus dem erwaehnten Posting:

          Windows style newlines are like this:
          <CR><LF> -> \r\n -> \015\012
          Mac style like this:
          <CR> -> \r -> \015
          Unix style like this:
          <LF> -> \n -> \012
          \012 -> 10 -> \n
          \015 -> 13 -> \r
          You shouldn't use \n or \r for replacing, because \n for windows is on unix enviroments \r\n and on mac enviroments \r - so you won't match newlines of foreign systems.

          Du solltest also besser Oktalwerte nehmen (\012 und \015) anstatt \n und \r. Und ob drei str_replace wirklich performanter sind als ein preg_replace, wage ich zu bezweifeln.

          Gruß,

          Dieter

          1. hi,

            Du solltest also besser Oktalwerte nehmen (\012 und \015) anstatt \n und \r.

            was daran besser/sicherer sein soll, leuchtet mir nicht ein.

            \015 entspricht doch nach der zitierten auflistung auf allen drei systemen einem \r return, und \012 auf allen einem \n newline bzw. line feed.

            gruß,
            wahsaga

            --
            "Look, that's why there's rules, understand? So that you _think_ before you break 'em."
            1. Hallo wahsaga,

              Stimmt, aus dem Posting wird das nicht wirklich ersichtlich, dafuer aber in diesem Feature Artikel

              Gruß,

              Dieter