Delphi-PRAXiS

Delphi-PRAXiS (https://www.delphipraxis.net/forum.php)
-   Programmieren allgemein (https://www.delphipraxis.net/40-programmieren-allgemein/)
-   -   nl2br(), nur nicht für HTML-Code (https://www.delphipraxis.net/73126-nl2br-nur-nicht-fuer-html-code.html)

Matze 12. Jul 2006 19:39


nl2br(), nur nicht für HTML-Code
 
Hi,

ich lese aus einer Datenbank mittels PHP einige Einträge aus, die unter anderem HTML-Code enthalten können.

Hier mal schnell ein kleines Beispiel solch eines Eintrags:


Code:
Bla bla blubb di wupp
hier eine neue zeile
und da noch eine
wuppdi und nun folgt eine Tabelle:

<table>
  <tr>
    <td>Hallo</td>
  </tr>
</table>

Hier wieder Text
mit Zeilenumbruch
Um die Absätze darzustellen nutze ich die PHP-Funktion nl2br(), die mit Absätze in ein
umwandelt.

Soweit so gut, nun wird jedoch absolut jeder Absatz umgwandelt (eigentlich verständlich), nur möchte ich natürlich den erzuegten Code so haben, dass nur der Text Absätze enthält.

Das was ich gerne hätte:

Code:
Bla bla blubb di wupp


hier eine neue zeile


und da noch eine


wuppdi und nun folgt eine Tabelle:




<table>
  <tr>
    <td>Hallo</td>
  </tr>
</table>

Hier wieder Text


mit Zeilenumbruch.
Erzeugt wird logischerweise das hier:

Code:
Bla bla blubb di wupp


hier eine neue zeile


und da noch eine


wuppdi und nun folgt eine Tabelle:




<table>[b]
[/b]
  <tr>[b]
[/b]
    <td>Hallo</td>[b]
[/b]
  </tr>[b]
[/b]
</table>[b]
[/b]

Hier wieder Text


mit Zeilenumbruch.
Wie kann ich HTML-Code von dieser Funktion ausschließen oder wie kann ich das ganze sauber lösen?

Eichhoernchen 12. Jul 2006 20:04

Re: nl2br(), nur nicht für HTML-Code
 
du könntest abfragen ob das letzte Zeichen in der Reihe ein > ist, dann ist es sehr wahrscheinlich das dort ein html tag ist!


Perfekt ist das aber nicht!

Khabarakh 12. Jul 2006 20:11

Re: nl2br(), nur nicht für HTML-Code
 
Vielleicht gibt es für dein Problem auch eine Funktion, aber ich würde einfach einen Regex auf den String loslassen. Soll heißen, nach Zeilen mit Text außerhalb von Tags suchen und diesen dann das
anhängen.

[add]
@Eichhörnchen: Du sagst es ;) . Deshalb empfehle ich Regular Expressions.
[/add]

S2B 12. Jul 2006 20:12

Re: nl2br(), nur nicht für HTML-Code
 
Naja, so einfach wird das nicht werden, da ja auch innerhalb bestimmter Tags Zeilenumbrüche vorkommen können (z.B. in td oder p). :gruebel:

Als grobe Lösung würde ich den Text in HTML- und nicht HTML-Zeilen aufteilen (mit preg_split() bzw. preg_match_all()) und dann nl2br() auf den Nicht-HTML-Teil anwenden. :wink: Am besten wird dann wohl sein, dass du das ganze schon beim Eintragen machst, um die Page Generation Time nicht unnötig zu strapazieren... :wink:

Edit: @Khabarakh: Oder so. :stupid:

Matze 12. Jul 2006 21:33

Re: nl2br(), nur nicht für HTML-Code
 
Hi,

die Lösung mit den regulären Ausdrücken klingt gut, nur müsst ihr wissen, dass ich diese nicht so sonderlich gut beherrsche. :stupid: Ich benötige sie eigentlich nur, um URLs umzuschreiben.

Könntet ihr mir evtl. ein kleines Beispiel geben, wie das aussehen könnte? Das Problem ist in meinen Augen, dass es ja auch mehrere HTML-Blöcke geben kann und nicht nur einen. Ich wüsste nicht, wie man das dynamisch lösen kann.

bigg 12. Jul 2006 22:05

Re: nl2br(), nur nicht für HTML-Code
 
moin,

wäre es dann nicht einfacher mit bbcode zu arbeiten, matze :stupid: ?

Mystic 12. Jul 2006 22:09

Re: nl2br(), nur nicht für HTML-Code
 
Naja, du könntest den Text zeichenweise durchgehen.

Für jedes '<' erhöhst du einen Counter um 1.
Für jedes '/>' oder '</' verringerst du ihn um 1.
Für jedes "\n" fügst du ein
ein, falls der Counter 0 ist.

Im Fall von '</' wird natürlich nicht 1 zum Counter dazugezählt.

Damit solltest du nur
bekommen, wenn du ausserhalb eines HTML-Blocks bist.

Ungetestet.

Matze 12. Jul 2006 22:25

Re: nl2br(), nur nicht für HTML-Code
 
Zitat:

Zitat von bigg
wäre es dann nicht einfacher mit bbcode zu arbeiten, matze :stupid: ?

Das habe ich mir auch schon überlegt, doch hilft mir das ja nichts, denn da müsste ich bei einer Tabelle der Übersichtlichkeit halber auch Absätze machen.

Zitat:

Zitat von Mystic
Naja, du könntest den Text zeichenweise durchgehen.

Das ginge, stimmt. Doch dann wird das ganze höchst unperformant und das möchte ich nicht.

fkerber 12. Jul 2006 22:33

Re: nl2br(), nur nicht für HTML-Code
 
Hi!

Bist du selber für den Text "verantwortlich"? Also wird er durch dich (oder dein Programm, Website) in die DB eingetragen?
Falls ja, würde ich um die HTML-Blöcke ne Art "Codewort setzen" und dann den Text eben gesplittet bearbeiten:

Neuer_Text := nl2br(alter_Text1)+alterCode1 + nl2br/alter_Text2) etc...


Ciao Frederic

bigg 12. Jul 2006 22:37

Re: nl2br(), nur nicht für HTML-Code
 
Ist doch im Grunde nichts weiter als bbcode^^ :wink:

Code:
[p]Absatz1-hier werden auch Zeilenumbrueche ersetzt[/p]

[p]Absatz2- und hier auch...[/p]

[html]
Tabellen, etc...
[/html]

Matze 12. Jul 2006 22:41

Re: nl2br(), nur nicht für HTML-Code
 
@Frederic: Ja, nur ich bin verantwortlich dafür, sonst würde ich auch kein HTML-Code zulassen. ;)

@Bigg: Ich dachte auch, dass ich einfach einen Tag um den HTML-Code setze und dieser Tag dann "weggeparst" wird und die darin enthaltenen Absätze nicht konvertiert werden. Das wäre eine sehr schöne Lösung finde ich, nur müsste ich da ja reguläre Ausdrücke verwenden und ich habe keine Ahnung, wie die aussehen müssen.

bigg 12. Jul 2006 23:12

Re: nl2br(), nur nicht für HTML-Code
 
Zitat:

Zitat von matze
@Bigg: Ich dachte auch, dass ich einfach einen Tag um den HTML-Code setze und dieser Tag dann "weggeparst" wird und die darin enthaltenen Absätze nicht konvertiert werden. Das wäre eine sehr schöne Lösung finde ich, nur müsste ich da ja reguläre Ausdrücke verwenden und ich habe keine Ahnung, wie die aussehen müssen.

Ach was, reguläre Ausdrücke benötigst du dafür nicht, ledglich eine kleine Auseinandersetzung mit einem für dich doch nicht unbekannten Thema. Du hast doch einen Editor mit Syntaxhighlighting geschrieben, der im Grunde nach dem selben Schema funktioniert.

1. In allen nicht HTML-Tags musst du HTML deaktivieren, indem du die Sonderzeichen "<" und ">" ersetzt.
2. Du benötigst eine Funkion ähnlich pos() die Anfang und Ende des jeweiligen Tags suchen.
Die Spitzen klammern werden nur dann ersetzt, wenn Anfang und Ende existieren. Da beide Tags die gleiche Länge haben kannst du sogar überschreiben.

3. ...

Wie wäre es, wenn du das ganze mal in Delphi umsetzt, kommentierst und nach PHP portierst? :>
Oder du suchst dir eine fertige Lösung bzw. passt diese dann noch an. Dat kriste doch hin ;-)

ehoffman 13. Jul 2006 02:04

Re: nl2br(), nur nicht für HTML-Code
 
Hallo zusammen,

normalerweise lese ich hier nur mit, da ich zu den Delphi-Problemen nie wirklich etwas gutes sagen kann :-) In diesem Fall kann ich aber durchaus auch etwas beitragen (denke ich zumindest). Grundsätzlich sollte die gesuchte Funktionalität mit folgender Regular Expression nach der in Perl verwendeten Syntax machbar sein (da nach PHP gefragt ist der Code auch in PHP):

Delphi-Quellcode:
preg_replace("/([^>])[\r\n]/", "\\1
", $input);
Damit werden alle Zeilenende (\r oder \n) mit einem "
" ersetzt die nicht an einem geschlossenen HTML-Tag enden. Insgesamt würde ich das dann etwa folgendermassen verwenden:

Delphi-Quellcode:
<?php
// Beispiel Eingabe aus dem Posting
$input = "Bla bla blubb di wupp\n".
         "hier eine neue zeile\n".
         "und da noch eine\n".
         "wuppdi und nun folgt eine Tabelle:\n".
         "\n".
         "<table>\n".
         " <tr>\n".
         "   <td>Hallo</td>\n".
         " </tr>\n".
         "</table>\n".
         "\n".
         "Hier wieder Text\n".
         "mit Zeilenumbruch\n";

// Ersetze Windows Zeilenendungen durch ein einfaches \n wie unter UNIX ueblich
$input = preg_replace("/\r\n/", "\n", $input);

// Ersetze Mac oder UNIX Zeilenendungen durch ein
 wenn nicht hinter
// schließenden HTML-Tag
echo preg_replace("/([^>])[\r\n]/", "\\1
", $input);
Damit werden somit alle Zeilenendungen durch "
" ersetzt die sich nicht direkt hinter einem schließenden HTML-Tag befinden - es werden also auch die Zeilenenden erfasst die innerhalb eines HTML-Tags liegen, z.B. bei:

Delphi-Quellcode:
$input = "Bla bla blubb di wupp\n".
         "hier eine neue zeile\n".
         "und da noch eine\n".
         "wuppdi und nun folgt eine Tabelle:\n".
         "\n".
         "<table>\n".
         " <tr>\n".
         "   <td>Hallo\n".
         "   auch hier ist noch Text\n".
         "   und hier sowieso\n".
         "   aber nun ist genug</td>\n".
         " </tr>\n".
         "</table>\n".
         "\n".
         "Hier wieder Text\n".
         "mit Zeilenumbruch\n";
Die Bedingung in obigem Regex, wenn kein "
" gesetzt werden soll ist das vor dem Zeilenumbruch ein ">" steht. Eventuelle Leerzeichen (wie hier im Beispiel zur Formatierung genutzt) bleiben erhalten. Es sollte auch darauf geachtet werden, dass alle ">" die nicht mit HTML-Tags zu tun haben (z.B. in math. Formeln) und nach denen ein zu konvertierendes Zeilenende steht vor der Konvertierung der Zeilenenden verschwunden sind, da es sonst nicht konvertiert werden würde. Hier könnte die PHP-Funktion "htmlspecialchars" helfen, da aber im Text HTML-Tags vorkommen können kann die Funktion nicht verwendet werden (auch die HTML-Tags selber würden damit geändert). Das muss also irgendwie im Editor geleistet werden - sprich HTML-Entities "abfangen" und ersetzen.

Noch eine Anmerkung: Das Ganze sollte im Prinzip funktionieren, aber HTML Code kann manchmal recht komplex werden - insbesondere wenn der Editor nicht bekannt ist - insofern keine Garantie das der Code in jedem Fall zum gewünschten Ergebnis führt :???:

Viele Grüße,
Eike

Matze 13. Jul 2006 06:03

Re: nl2br(), nur nicht für HTML-Code
 
Hi

Zitat:

Zitat von bigg
2. Du benötigst eine Funkion ähnlich pos() die Anfang und Ende des jeweiligen Tags suchen.
Die Spitzen klammern werden nur dann ersetzt, wenn Anfang und Ende existieren. Da beide Tags die gleiche Länge haben kannst du sogar überschreiben.

Nur kann das manuelle Parsen recht langsam werden, darum wollte ich das nicht so. ;)

Zitat:

Zitat von ehoffman
In diesem Fall kann ich aber durchaus auch etwas beitragen (denke ich zumindest).

Danke, das ist schonmal super, nur noch nicht ganz perfekt. :thumb:

Bei Code wie:

Code:
[...] hier steht ein text

<div class="center">[img]...[/img]</div>
Wird nach der Anwendung des regulären Ausdrucks kein Absatz zwischen dem text und dem darauf folgenden Bild gemacht. Der Text klebt also direkt über dem Bild, was mir noch nicht gefällt. Ansonsten funktioniert es, soweit ich das sehen kann, alles bestens. Aber auch mit dem kleinen Schönheitsfehler könnte ich leben. ;)

Zitat:

Zitat von ehoffman
Noch eine Anmerkung: Das Ganze sollte im Prinzip funktionieren, aber HTML Code kann manchmal recht komplex werden - insbesondere wenn der Editor nicht bekannt ist - insofern keine Garantie das der Code in jedem Fall zum gewünschten Ergebnis führt :???:

Ich schreibe jedes Zeichen von Hand, nutze also keinen WYSIWYG-Editor oder Ähnliches, lediglich einen normalen Editor mit Syntaxhighlightning.

Was mich dennoch interessieren würde (ich weiß nicht, ob ich das so mache):
Angenommen, ich fasse solche komplexeren HTML-Blocke in einen -BBCode. Wie kompliziert wäre es dann, das mit regulären Ausdrücken zu lösen?

ehoffman 13. Jul 2006 13:27

Re: nl2br(), nur nicht für HTML-Code
 
Hallo,

Zitat:

Zitat von Matze
Wird nach der Anwendung des regulären Ausdrucks kein Absatz zwischen dem text und dem darauf folgenden Bild gemacht. Der Text klebt also direkt über dem Bild, was mir noch nicht gefällt. Ansonsten funktioniert es, soweit ich das sehen kann, alles bestens. Aber auch mit dem kleinen Schönheitsfehler könnte ich leben. ;)

Damit sollte es gehen:
Delphi-Quellcode:
preg_replace("/(([^>])[\r\n])|^([\r\n])/m", "\\1
", $input);
Zitat:

Zitat von Matze
Was mich dennoch interessieren würde (ich weiß nicht, ob ich das so mache):
Angenommen, ich fasse solche komplexeren HTML-Blocke in einen -BBCode. Wie kompliziert wäre es dann, das mit regulären Ausdrücken zu lösen?

Also soooo super toll kenne ich mich mit den Perl Regex auch nicht aus, aber meiner Meinung nach würde diese Vorgehensweise das Ganze nicht sonderlich erleichtern. Du müßtest dann zunächst mal die Eingabe aufteilen in "Nicht-HTML" und in "HTML" (also innerhalb von ). Das ginge mit preg_replace und einer zusätzlichen Funktion recht einfach. Die Funktion selber ersetzt dann quasi die Leerzeichen. Das würde also pro gefundenem Block (HTML/Nicht-HTML) ein Funktionsaufruf sein. Da sollte obiges regex schneller arbeiten.

Ansonsten kann man das auch "von Hand" also ohne regex zerlegen - aber das kommt meiner Meinugn nach letztendlich alles auf das gleich raus. :-)

Viele Grüße,
Eike

S2B 13. Jul 2006 15:05

Re: nl2br(), nur nicht für HTML-Code
 
Warum parst du eigentlich nicht beim Absenden und trägst das ganze (evtl. in einer neuen Spalte) direkt so in die Datenbank ein? Das sollte in jedem Fall schneller sein, egal, welche Lösung du verwendest... :wink:

Matze 13. Jul 2006 16:52

Re: nl2br(), nur nicht für HTML-Code
 
Zitat:

Zitat von ehoffman
Damit sollte es gehen:
Delphi-Quellcode:
preg_replace("/(([^>])[\r\n])|^([\r\n])/m", "\\1
", $input);

Wunderbar, herzlichen Dank. :thumb:

Stimmt, ob das andere viel bringt weiß ich auch nicht.

Zitat:

Zitat von S2B
Warum parst du eigentlich nicht beim Absenden und trägst das ganze (evtl. in einer neuen Spalte) direkt so in die Datenbank ein? Das sollte in jedem Fall schneller sein, egal, welche Lösung du verwendest... :wink:

Schneller beim Auslesen ja, da gebe ich dir recht. Doch wenn ich dann einen Beitrag bearbeiten möchte und überall dann diese zusätzlichen HMTL-Tags habe, dann ist das sehr unübersichtlich und erschwert mir das Editieren nur unnötig.
Sollte es einmal merklich langsamer werden, habe ich ja immer noch die Option, das ganze zu optimieren und deinen Vorschlag umzusetzen.


Alle Zeitangaben in WEZ +1. Es ist jetzt 11:39 Uhr.

Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024-2025 by Thomas Breitkreuz