Seite 1 von 1

Import von Fremddaten in ein Forum - Filterproblem - Zitat

Verfasst: 30.01.2007 20:58
von mgutt
Hallo,

ich habe Nachrichten in dem Format:
Hier kann was stehen
: Zitatanfang
: ...
: ...
: Zitatende
Hier kann was stehen
Zusätzlich gibt es aber noch sowas:
Hier kann was stehen
::: Zitatanfang
::: ...
::: Zitatende
Hier kann was stehen
:: Zitatanfang
:: ...
:: Zitatende
Hier kann was stehen
: Zitatanfang
: ...
: Zitatende
Hier kann was stehen
D.h. ich müsste klar erkennen wann ein Zitat beginnt und wann es endet.

Ich denke mal an Hand "\n\r(:|::|:::|::::)(.*)\n\r(:|::|:::|::::)" könnte man das lösen. Dann muss ich aber klar machen, dass der jeweils erste und letzte das Anfang und das Ende darstellt.

Am Ende importiere ich die Texte so, dass die jeweiligen Zitate in den Quote-Tags stehen.

Gruß

Verfasst: 30.01.2007 21:30
von Xwitz
Wie sieht es aus, wenn es verschachtelt ist und wie war gleich noch mal die Frage?

Verfasst: 31.01.2007 00:18
von gn#36
Es muss ja irgend eine Markierung geben für den Start und das Ende eines Zitats.
Ich würde dann so vorgehen:
1. Durchsuche den Text bis zum ersten Start eines Zitats.
2. Stelle merken
3. Nach weiteren Starts/Ende eines Zitats suchen
4. Wird ein Ende gefunden, dann diesen mit dem zuletzt gefundenen Anfang verknüpfen. (was auch immer man damit vorhat, z.B. durch anderen Code ersetzen, den Text dazwischen verarbeiten, was auch immer), dann diesen Start aus der gemerkten Liste entfernen
5. Wird ein weiterer Start gefunden den dann ebenfalls einfach nur merken.
6. Weiter bis zum Ende des Texts
7. Sollten dann noch ungepaarte Starts über sein oder man ein Ende zu viel finden, dann stimmt irgendwas am Code nicht (z.B. Reihenfolge falsch)

Verfasst: 31.01.2007 20:23
von mgutt
Wie Du siehst leiten Doppelpunkte das Zitat ein und aus. Es ist aber kein wirklicher Anfang oder ein Ende erkennbar.

Man weiß nur, dass es immer so aussieht:
:: Ich
:: bin
:: ein
:: Zitat
D.h. ich müsste nach dem ersten Doppelpunktkonstrukt suchen. Klar. Dann habe ich den Anfang. Wie suche ich dann aber den letzten und zwar unter der Voraussetzung, dass davor jede Zeile das gleiche Doppelpunktkonstrukt hatte. Am Ende muss ich dann die Doppelpunkte löschen, aber das wird denke ich kein Problem werden.

@ xwitz
Verschachtelte kann man glaube ich nicht identifizieren. Außer man versucht es an Hand der Häufigkeit der Doppelpunkte. Im zweiten Beispiel das könnte ja ein verschachteltes Zitat sein, wenn die Zwischenkommentare rausfallen. Aber ich bezweifel, dass die Daten immer so sauber übergeben werden.

Verfasst: 01.02.2007 13:37
von Xwitz
Und das erste Zitat hat immer die meisten Doppelpunkte? Sehr eigenartig.

Man könnte zuerst mal in allen Datensätzen suchen, ob es überhaupt mehr als z.B. fünf aufeinanderfolgende Doppelpunkte am Zeilenanfang gibt. Wenn man die Höchstzahl hat der Reihe nach mit den meisten beginnend die Positionen der Doppelpunktkombis finden. Zwischen den Positionen nach Zeilenumbrüchen suchen und bei mehr als einem Umbruch die weiteren Positionen verwerfen (das dürfte aber eigentlich nicht vorkommen). Am Zeilenumbruch hinter der letzten einen schließenden quot und vor der ersten einen öffnenden quot einfügen (in der Reihenfolge wegen der sich sonst ändernden Position) und dann die Doppelpunkte (in der Anzahl) entfernen. Wenn Positionen verworfen werden mußten, dann das gleiche Spiel noch mal, sonst das gleiche Spiel noch mal mit der nächstkleineren Zahl an Doppelpunkten am Zeilenanfang.

Wenn es verschachtelt ist und wenn jemand manuell Doppelpunkte an den Anfang gesetzt hat, geht es aber vermutlich schief.

PS: Kannst du es nicht gleich zeilenweise untsuchen? Ist das eine Textdatei oder was?

Verfasst: 01.02.2007 15:16
von mgutt
Ja kann ich. War eine html-Datei, auf die ich aber noch zugreifen kann. Mittlerweile sind die Daten auch in der Datenbank zur Verfügung.

Aber ich kann ja line für line per Zeilenumbruch (\n) ermitteln.

Ich hoffe mal nicht, dass einer eine Zeile mit einem Doppelpunkt angefangen hat. Wissen tue ich es aber nicht. Ich denke aber dass das bei nichtmal 0,1% vorkommen wird.

Das mit der Doppelpunktanzahl ist wie bei Emails.

>> 1. Zitat
>> 1. Zitat
> 2. Zitat
> 2. Zitat

Dann kann man ja auch dazwischen schreiben.

Laut dem Beispiel würde es dann so sein, dass ich wenn ich bei Zeile 3 bin, am Ende von Zeile 2 ein [/quote] (mit bbcode_id natürlich) hinsetze. Ich denke das sollte zu schaffen sein. Ich fange dann mit der höchsten Doppelpunktanzahl an und arbeite mich dann runter.

\n:::::
\n::::
\n:::
usw.

Ich probier das mal und melde mich dann noch mal zurück.

Gruß

Verfasst: 01.02.2007 16:47
von Banger
Hier mal ein Beispiel, dass das Nesting der Zitate berücksichtigt...

Code: Alles auswählen

<?php

$txt = 'Hier kann was stehen
::: Zitatanfang
::: ...
::: Zitatende
Hier kann was stehen
:: Zitatanfang
::: eingebettetes Zitat

Hier steht schon wieder was dazwischen

:: Zitatende
Hier kann was stehen
: Zitatanfang
: ...
: Zitatende
Hier kann was stehen
:: noch ein Zitat am Ende
::: sogar eingebettet!
:: ende letztes Zitat';

$in = preg_split('/(\r\n|\r|\n)/', $txt, -1, PREG_SPLIT_DELIM_CAPTURE);
$out = '';
$qlevel = 0;
$open = 0;
$lbr = '';

while($in) {
    if(preg_match('/^(:+)\s(.*)$/', $buf = array_shift($in), $r)) {
        $thislvl = strlen($r[1]);
        $buf = $r[2];
    } else
        $thislvl = 0;

    $qr = '';

    switch(TRUE) {
        case $thislvl > $qlevel:
            $open += $thislvl-$qlevel;
            for($i=$qlevel; $i<$thislvl; $i++)
                $qr .= '[quote'.$i.']';
            $out .= $lbr.$qr.$buf;
            break;
        case $thislvl < $qlevel:
            $open -= $qlevel-$thislvl;
            for($i=$qlevel-1; $i>=$thislvl; $i--)
                $qr .= '[/quote'.$i.']';
            $out .= $qr.$lbr.$buf;
            break;
        default:
            $out .= $lbr.$buf;
    }
    $qlevel = $thislvl;
    if($in) $lbr = array_shift($in);
}

#offene quotes schließen:
for($i=$open; $i; $i--)
    $out .= '[/quote'.$i.']';

#jetzt wird's lustig: überflüssige Zitateinrückungen entfernen

function remQuotes($txt, $lvl=0) {
    if(!preg_match_all('/\[quote'.$lvl.'\](.*)\[\/quote'.$lvl.'\]/Us', $txt, $r))
        return $txt;
    foreach(array_keys($r[0]) as $k) {
        $buf = trim(preg_replace('/\[quote'.($lvl+1).'\](.*)\[\/quote'.($lvl+1).'\]/Us', '', $r[1][$k]));
        $repl = $buf ? $r[1][$k] : $r[0][$k];
        $txt = str_replace($repl, remQuotes($r[1][$k], $lvl+1), $txt);
    }
    return preg_replace('/quote\d+\]/', 'quote]', $txt);
}

$out = remQuotes($out, 0);

?>
-----AUSGABE------

Hier kann was stehen
Zitatanfang
...
Zitatende
Hier kann was stehen
Zitatanfang
eingebettetes Zitat
Hier steht schon wieder was dazwischen
Zitatende
Hier kann was stehen
Zitatanfang
...
Zitatende
Hier kann was stehen
noch ein Zitat am Ende
sogar eingebettet!
ende letztes Zitat
-------

Naja, noch nicht ganz perfekt...

Verfasst: 08.02.2007 14:33
von mgutt
Danke für den Ansatz.

Mir ist beim Probieren aufgefallen, dass die Daten ziemlich bescheiden sind.

z.B. sieht ein Zitat so aus:

: Zitatanfang
: Zitat

: Zitat
: Zitat

: Zitatende

D.h. doppelte Zeilenumbrüche haben keine Kennzeichnung, dass sie immernoch im selben Zitat liegen. Schon komisch.