| 

.NET C# Java Javascript Exception

4
Ich versuche Zeilenumbrüche zwischen <table> und </table> mit PHP zu entfernen. Die Tabelle geht über mehrere Zeilen. Ich bin schon soweit, dass ich den Code matchen kann, verstehe aber den Syntax von preg_replace nicht.

Das Matching klappt schon mal mit
/(?<=\<table).*(?=\<\/table\>)/s
aber weiter bin ich noch nicht.

<p>Das ist ein test</p>
<table class="testklasse" id="irgendwas">
<tr><td>Bitte nicht umbrechen</td></tr>
<tr><td>Bitte auch nicht umbrechen</td></tr>
</table></p>
<p>Und hier auch</p>


Könnte mir jemand auf die Sprünge helfen?
Herzlichen Dank!
17.01.2012
holgi 63 1 4
holgi 63 1 4
Mich verwirrt der Satz "Bitte nicht umbrechen" in den Tabellen-Zellen wenn du innerhalb von <table> umbrechen willst. Magst du vll noch den Code des erwarteten Ergebnises posten?
Nicolai Schönberg 17.01.2012
Meinst du, dass bei TR automatisch umgebrochen wird? Vllt meinst du auch die automatische Umbrechung im Browser, weil in deinem Code wird nichts umgebrochen, jedenfalls nicht HTML.
LiRo 17.01.2012
1
Oder willst du alle "\r\n"s durch ein <p></p> ersetzen, nur nicht in Tabellen? Wieso so umständlich? Wenn du schon HTML verwendest (und nicht BBCode o.ä.), dann kannst du genauso <br /> oder <p></p> selber schreiben.
LiRo 17.01.2012
3 Antworten
2
Moin,

da ich nun verstanden habe was du tun willst, habe ich eine Lösung erarbeitet.
Hier das Ausgabe Beispiel: grrbrr.de/reg.php

Und hier der Code
<?php
$str = '<p>Das ist ein test</p>
<p><table></p>
<p><tr><td>Zelle 1</td></tr></p>
<p><tr><td>Zelle 2</td></tr></p>
<p></table></p>
<p>Letzte Zeile</p>';

$pattern = '/(.*)(<p>)(<table>.*<\/table>)(<\/p>)(.*)/ms';
$matchCount = preg_match_all($pattern, $str, $matchResult);

?>


<fieldset>
<legend>Kompletter Match</legend>
<pre>
<?=htmlentities($matchResult[0][0])?>
</pre>
</fieldset>

<fieldset>
<legend>Group Match 1 (Alles vor &lt;table&gt;)</legend>
<pre>
<?=htmlentities($matchResult[1][0])?>
</pre>
</fieldset>

<fieldset>
<legend>Group Match 2 (&lt;p&gt; direkt vor &lt;table&gt;)</legend>
<pre>
<?=htmlentities($matchResult[2][0])?>
</pre>
</fieldset>
<fieldset>
<legend>Group Match 3 (Inhalt von &lt;table&gt;)</legend>
<pre>
<?=htmlentities($matchResult[3][0])?>
</pre>
</fieldset>
<fieldset>
<legend>Group Match 4 (&lt;/p&gt; direkt nach &lt;table&gt;)</legend>
<pre>
<?=htmlentities($matchResult[4][0])?>
</pre>
</fieldset>
<fieldset>
<legend>Group Match 5 (Alles nach &lt;table&gt;)</legend>
<pre>
<?=htmlentities($matchResult[5][0])?>
</pre>
</fieldset>
<fieldset>
<legend>&lt;p&gt; und &lt;/p&gt; aus Group Match 3 entfernen</legend>
<pre>
<?php
$sub = $matchResult[3][0];
$sub = str_replace('<p>','', $sub);
$sub = str_replace('</p>','', $sub);
echo htmlentities($sub);
?>
</pre>
</fieldset>
<fieldset>
<legend>Alles zusammen bauen</legend>
<pre>
<?php
echo htmlentities($matchResult[1][0])
.htmlentities($sub)
.htmlentities($matchResult[5][0])
?>
</pre>
</fieldset>


Ich habe also den String in mehrere Teilergebnisse zerlegt und dann wieder zusammengebaut. Ich bin sicher das es noch hübscher geht. Wer traut sich? :)

Grüße
18.01.2012
Nicolai Schönberg 2,4k 2 9
0
Ich wollte eigentlich automatisch jeden Umbruch in einem textfeld in "<p></p>" setzen. Ausnahme: Kommt im Text eine Tabelle vor, soll nicht umgebochen werden. War das soweit verständlich?
17.01.2012
holgi 63 1 4
1
Ändere deine Frage oder schreibe das als Kommentar. Aber -bitte- nicht als eigene Antwort!
LiRo 17.01.2012
Ein leeres <p></p> Element sollte nicht verwendet werden. Das p - Element (Paragraph) steht semantisch für einen Absatz und ist ein Block Element. Ein reiner Zeilenumbruch ist ein <br> (bzw. <br /> im XHTML). Und dass was Du da oben als Beispiel hast ist nicht valide, denn eine Tabelle darf nicht in einem P - Element vorkommen. (Zumal nach dem /table auch nur das /p geschlossen, aber nie geöffnet wird.
Xantiva 17.01.2012
Poste bitte einfach zwei Beispiele, 1) Das hab ich jetzt 2) So soll es aussehen. Und wenn du schon dabei bist, erklär uns doch auch warum du das so machen möchtest. Ich werde das Gefühl nicht los, das du dein Problem von hinten durch die Brust ins Auge lösen willst (nicht bös gemeint). Grüße
Nicolai Schönberg 17.01.2012
1
@Nicolai hier das was ich bislang habe:

<p>Das ist ein test</p>
<p><table></p>
<p><tr><td>Zelle 1</td></tr></p>
<p><tr><td>Zelle 2</td></tr></p>
<p></table></p>
<p>Letzte Zeile</p>

Und das soll bei rauskommen

<p>Das ist ein test</p>
<table>
<tr><td>Zelle 1</td></tr>
<tr><td>Zelle 2</td></tr>
</table>
<p>Letzte Zeile</p>
holgi 17.01.2012
0
Hi,

also ich verstehe die Anforderung immer noch nicht genau. Willst Du das unnötige </p> nach </table> entfernen?

Naja. Wie dem auch sei
/(?<=\<table).*(?=\<\/table\>)/s

selektiert die alles zwischen <table und </table> exclusiv und gierig (greedy). D.h. Wenn Du 2 Tabellen hast, dann alles, was in folgendem Codeblock unterstrichen ist...

<p>Das ist ein test</p>
<table class="testklasse" id="irgendwas">
<tr><td>Bitte nicht umbrechen</td></tr>
<tr><td>Bitte auch nicht umbrechen</td></tr>
</table>
<p>asd</p>
<table class="testklasse" id="irgendwas anderes">
<tr><td>Bitte nicht umbrechen</td></tr>
<tr><td>Bitte auch nicht umbrechen</td></tr>
</table>
<p>Und hier auch</p>


non-greedy wird es mit
/(?<=\<table).*?(?=\<\/table\>)/s

Damit wird beim ersten Vorkommen von </table> aufgehört.

Das Problem sind dann aber noch verschachtelte Tabellen, da dabei weder das erste, noch das letzte Vorkommen von </table> das richtige ist..
Hier geht mein php-Regex - Wissen aber aus. In .NET könnte man das noch mit balanced groups lösen. Schön ist es aber nicht mehr - HTML ist einfach keine reguläre Sprache (Regex ist es auch nicht mehr wirklich, daher geht es oft trotzdem - wird aber nicht schön).

Ein HTML-Parser wäre daher im Normalfall auch die weitaus klügere Wahl. http://stackoverflow.com/questions/3577641/how-to-parse-and-process-html-with-php/3577662#3577662
17.01.2012
WolfgangKluge 1,0k 2 7
Bei verschachtelten Strukturen stellt man das RegEx auf greedy und benutzt eine RegEx-Suchfunktion mit ein Callback. In dem Callback ruft man das RegEx auf, das ruft wieder das Callback auf und immer so weiter.
LiRo 17.01.2012
hmmm... ne, greedy darf es ja gar nicht sein.
LiRo 17.01.2012

Stelle deine Php-Frage jetzt!