Seite 1 von 1

[PHP] Problem bei Umsetzung eines Lexikons

Verfasst: 01.09.2006, 14:00
von Thies
Hallo,

ich brauche mal Euren Rat, vielleicht hat jemand Vorschläge, wie ich meine Idee (besser) umsetzen kann.

Im Rahmen der Erweiterung eines CMS arbeite ich an der Integration eines Lexikons. Das klappt auch alles soweit ganz gut. Als eine Option will ich eine automatische Verlinkung der Texte zu anderen Einträge erreichen. Also wenn z.B. in einem Text das Wort Bildungssystem vorkommt und das Wort Bildungssystem ein Begriff des Lexikons ist, dann soll automatisch zum Begriff Bildungssystem verlinkt werden.

Das könnte man theoretsich erreichen, dass nach der Erfassung eines Eintrages der Text sofort geprüft wird. Hat aber den Nachteil, dass bisherige Einträge nicht geprüft werden, ob dort im Text der neue Eintrag auch vorkommt. Und on-the-fly nach der Erfassung eines Eintrages alle Einträge zu prüfen, dürfte den Server je nach Anzahl der Einträge ganz schön schaffen :D

Also will ich wie folgt umsetzen:

Einmal in der Nacht wird per CronJob das Lexikon deaktiviert und alle Einträge geprüft. Danach wird das Lexikon wieder aktiviert. Zur Umsetzung nutze ich einen BBCode [lex]...[/lex]

Das bekomme ich auch hin. Die Idee ist, alle [lex] und [/lex] eines Textes zu löschen und danach per str_replace die Begriffe durchlaufen zu lassen, z.B. per

Code: Alles auswählen

foreach ($words as $i) {
   str_replace("/($i)/", " [lex]$i[/lex] ", $string);
}
Damit werden alle Worte wie Bildungssystem in entsprechende Links wie https://www.domain.de/lex/Bildungssystem umgewandelt.

Worte wie Bildungssysteme werden davon aber nicht erfasst, also will ich das der Erfasser in solchen Fälle doch manuell einen BBCode erfassen kann:

[lex="Bildungssystem"]Bildungssysteme[/lex]

Bei der Löschroutine würde aber das schliessende [/lex] gelöscht werden. Und jetzt weiss ich nicht mehr, wie ich das sinnvoll umsetzen kann.

Hat jemand von Euch eine Idee oder einen besseren Umsetzungsvorschlag?

Danke im Voraus

Frank-Andre Thies

Verfasst:
von

Verfasst: 01.09.2006, 14:43
von marc75
on the fly beim Aufruf des Beitrages, das heisst erst gar kein BBcode dafür extra einfügen. Sondern den Text vor der Ausgabe parsen und dann mit den Links zum lexikon ausgeben.

Verfasst: 01.09.2006, 21:19
von phiro
Hallo,

wie schon gesagt wurde kann das ganze on the fly erledigen, was allerdings bei sehr vielen Begriffen zu hoher Last führt.

Eine Alternative wäre zum Beispiel ein RegEx, der leichte Abweichungen in der Endsilbe verzeiht, zum Beispiel etwa so...

Code: Alles auswählen

$regex = '&#40;&#91; &#40;>&#93;&#41;&#40;'.$name.'&#91;a-z&#93;&#123;0,3&#125;&#41;&#40;&#91; &#41;<,\.&#93;&#41;';
der würde zum Beispiel auch nicht anschlagen, wenn direkt auf den Begriff eine öffnende eckige Klammer folgt...

Oder eben einen exakter arbeitenden RegEx wiezum Beispiel

Code: Alles auswählen

$regex = '&#40;&#91; &#40;>&#93;&#41;&#40;'.$name.'&#41;&#40;&#91; &#41;<,\.&#93;&#41;';
der trotzdem alles in BB Code verschont.

Gruß

Philipp

[/code]

Verfasst:
von

Verfasst: 04.09.2006, 21:11
von Thies
marc75 hat geschrieben:on the fly beim Aufruf des Beitrages, das heisst erst gar kein BBcode dafür extra einfügen. Sondern den Text vor der Ausgabe parsen und dann mit den Links zum lexikon ausgeben.
Das hilft aber wenig weiter, weil dann ja die bisherigen Einträge nicht auf den neuesten Eintrag geprüft werden.

@phiro
Danke, aber leider klappt Dein Code nicht so ganz zu Löschen :(

Code: Alles auswählen

$check_text6 = preg_replace&#40;"&#40;&#91; &#40;>&#93;&#41;&#40;.*?&#41;&#40;&#91; &#41;<,\.&#93;&#41;", "$0", $check_text6&#41;;
Dann kommt der Fehler Compilation failed: unmatched parentheses at offset 5

Alternativ hatte ich probiert

Code: Alles auswählen

$check_text6 = preg_replace&#40;"/\&#91;lex\&#93;&#40;.*?&#41;\&#91;/lex\&#93;/", "$0", $check_text6&#41;;
Dann kommt der Fehler Unknown modifier 'l'

Ziel ist es, dass [lex]...[/lex] in ... umgewandelt wird.

Danke vorab

Frank-Andre

Verfasst: 04.09.2006, 21:32
von Southmedia
dann musst du das /lex escapen: \/lex

Verfasst: 05.09.2006, 00:05
von saudepp
anstatt alle einträge jede nacht abzugleichen, würde ich so vorgehen:
* die neuen einträge des tages in eine liste schreiben, sagen wir mal du hast 10 neue Einträge
* in der nacht wird diese liste aufgerufen, und der inhalt aller bisherigen einträge nach diesen 10 Neueinträgen durchsucht
* dies kann nicht so lange dauern, durchsuche mal ein 1000 Seiten Word-File nach einem bestimmten Wort, dauert max. 10 sec pro Query. Und SQL ist wesentlich schneller als MS doof.
* nach dem du die zu ändernden alten einträge gefunden hast, mußt du nur noch eine routine schreiben, die das unverlinkte keyword mit dem verlinkten ersetzt, und dies natürlich VOR dem parsen ...

gruß -saudepp

Verfasst: 05.09.2006, 07:40
von Fantomas
phiro hat geschrieben:wie schon gesagt wurde kann das ganze on the fly erledigen, was allerdings bei sehr vielen Begriffen zu hoher Last führt.
Nein, die RegEx verursachen auch bei vielen aufrufen keine große Last. Das lesen des Beitrags aus der DB ist "teurer", als danach ein paar RegEx drüber laufen zu lassen.

F.

Verfasst: 05.09.2006, 20:12
von Thies
@Southmedia:
Danke ... ich habe den Wald vor lauter Bäumen nicht gesehen.

@saudepp:
das ist wirklich eine gute Idee, ich habe heute lange darüber nachgedacht. Ich muss dann "nur" noch vermerken, ob es ein Neueintrag, eine Begriffsänderung oder eine Löschung ist, damit ich alle Fälle treffe.

Mal sehen, wie ich das am besten umsetze :)

@Fantomas:
ich glaube, dass war auch gemeint, denn es müssen ja alle Einträge in der DB durchgearbeitet werden.

@all:
Jetzt komme ich an einer anderen Stelle nicht weiter und weiss gar nicht, wie man das realisieren kann. Ich ersetze die Begriffe in den Texten per

Code: Alles auswählen

$check_text5 = preg_replace&#40;"/&#40;\b$i\b&#41;/", "&#91;lex&#93;".$i."&#91;/lex&#93;", $check_text5&#41;;
wobei $i der jeweilige Begriff ist, der ersetzt werden soll. Das klappt auch grundsätzlich gut. Wenn ich aber ermöglichen lassen will, dass manuelle BBCodes erfasst werden können wie [lex="laborum"]labore[/lex], dann wird daraus leider [lex="[lex]laborum[/lex]"]labore[/lex]

Ich muss also angeben, dass kein [lex=.....] vorab und kein [/lex] nach dem (\b$i\b) stehen dürfen. Kann mir jemand erklären, wie man solche "Negierungen" erreichen kann?

Danke

Frank-Andre