In PyLucid v0.9 gibt es ein neues Lexikon Plugin. Es ersetzt alle vorhandenen Lexikon Begriffe in der erzeugten html Seite mit einem Link in das Lexikon und einer title information im link...
Das Problem: Ich verwende z.Z. eine sehr einfache funktion um die Wörter zu ersetzten. Ich mache einfach sowas in der Art: content = content.replace(" %s ", lexicon_info).
Das ersetzt aber auch die Wörter, wo ein Link überhaupt nicht erlaubt ist. Ich muß also viel mehr den html code analysieren und nur im eigentliche Text die Wörter ersetzten. Jemand eine Idee wie man das mit relativ wenig Aufwand machen kann?
EDIT1: Eine variante die mit einfallen würde: Das ganze nicht auf dem Server machen, sondern per jQuery die Sachen erledigen. Dort gibt es sicherlich eine Funktion dafür. Aber das wäre dumm, weil es dann nur mit JS gehen würde...
EDIT2: Ob es evtl. mit RE gehen würde? Nach dem Prinzip: ">(.*?)<" (Also nur in dem Bereich suchen)
Wörter in html text ersetzten...
Normaler Fliess-Text oder ein Absatz sollte doch in HTML immer in <p>-Tags sein?
EDIT: Du hast wohl auch editiert, jetzt verstehe ich, was du meinst... Ich würde halt einfach überprüfen, ob die übergeordneten Tags ein <a> beinhalten dürfen oder nicht...
EDIT: Du hast wohl auch editiert, jetzt verstehe ich, was du meinst... Ich würde halt einfach überprüfen, ob die übergeordneten Tags ein <a> beinhalten dürfen oder nicht...
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Ne, So einfach geht das nicht. Eine RE nach dem Motto "<p>(.*?)</p>" würde ja auch Links im Text treffen.
Mal ein Beispiel:
Quellen Text:
Wenn im Lexikon "PyLucid" vorhanden wäre, würde auch im Link Titel das Wort ersetzt.
Mal ein Beispiel:
Quellen Text:
Code: Alles auswählen
<p>Bla bla <a href="/en/blog/" title="The PyLucid developer blog" class="level_0">blog</a> foobar</p>
- Hyperion
- Moderator
- Beiträge: 7478
- Registriert: Freitag 4. August 2006, 14:56
- Wohnort: Hamburg
- Kontaktdaten:
Fällt denn lxml bei der Abhängigkeit "Django" noch so sehr ins Gewicht?jens hat geschrieben:Ja, aber dann brauche ich noch eine externe lib
Könnte man auch ein internes Modul her nehmen? Ich meine ich hab sowas ähnliches mal mit HTMLParser und sgmllib probiert. Aber das klappte nicht so doll...
Außerdem kann man ja auch reine Python-Module wie BeautifulSoup oder html5lib + ElementTree nutzen, die man notfalls mit der eigenen Anwendung mitliefern kann.
Ich würde mit Regexp 1 Tags von Text trennen und dann in dem Text, getrennt an Leerschritt, Komma, Punkt und ein paar anderen Zeichen, in dem Lexikon suchen, ggf. Links erzeugen und alles wieder zusammensetzen. Sind maximal 5 Zeilen Code. XML-Parser (außer man will auch mit Entities klarkommen, also wenn jemand ein antikes ä statt ä benutzen will) nicht nötig.
Stefan
Stefan
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Ja, ich werde wohl erstmal zu einer RE Lösung greifen. Das Lexikon ist ja nur ein nettes Zusatzfeature. Zusätzliche Abhängigkeiten sind IMHO nicht gerechtfertigt, wenn es auch ohne geht...
@sma: Vorschläge wie eine RE Lösung aussehen kann?
@sma: Vorschläge wie eine RE Lösung aussehen kann?
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Ja, das wäre eine "Not Lösung". Wäre aber schöne, wenn es immer gehtsnafu hat geschrieben:Wie wäre es dann, das Lexikon-Feature optional anzubieten? Es wird dann halt freigeschaltet, wenn es den gewünschten Parser findet.

Hab die öffentliche Test Seite http://www.pylucid.de aktualisiert. Dort kann man sich das mal anschauen.
Im Lexicon ist allerdings bisher nur der Begriff "PyLucid" in englisch und deutsch. Auf der Hauptseite kann man sehen, das jedes "PyLucid" Wort ersetzt wird mit einem Link zu http://www.pylucid.de/?lexicon=PyLucid
In der "Update" liste, auf der Hauptseite oder im http://www.pylucid.de/en/SiteMap/ kann man auch sehen, das die jetzige Implementierung schaden anrichtet

Code: Alles auswählen
import re
def sub_text(html, f):
def r(m):
s = m.group(1)
return s and (f(s) or s) or m.group()
return re.sub(r"(?u)<[^>]*>|(\w+)", r, html)
def f(w):
if w == u'weiter':
return u'<b>WEITER</b>'
print sub_text(u'<html><a href="foo.bar/?a=x">dingens</a>und so weiter</html>', f)
Stefan
Zuletzt geändert von sma am Sonntag 23. August 2009, 09:03, insgesamt 1-mal geändert.
- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
Das sieht schon mal nach einer Lösung aus, die besser ist als meine 
Werde ich nächste Woche mal testen. Danke!
Daneben sollte ich mir noch Gedanken dazu machen, wie man die Datenbank Zugriffe im Zaum hält. Denn bei langen Texten hätten wir sehr viele, wenn man einfach bei jedem Wort prüfen würde, ob es in der DB ist.
Aber man könnte es auch so machen, das man sich erstmal alle Wörter (mit Alias, den gibt es auch) vorab beschafft.
Außerdem gibt es irgendwann wieder den Page cache

Werde ich nächste Woche mal testen. Danke!
Daneben sollte ich mir noch Gedanken dazu machen, wie man die Datenbank Zugriffe im Zaum hält. Denn bei langen Texten hätten wir sehr viele, wenn man einfach bei jedem Wort prüfen würde, ob es in der DB ist.
Aber man könnte es auch so machen, das man sich erstmal alle Wörter (mit Alias, den gibt es auch) vorab beschafft.
Außerdem gibt es irgendwann wieder den Page cache

- jens
- Python-Forum Veteran
- Beiträge: 8502
- Registriert: Dienstag 10. August 2004, 09:40
- Wohnort: duisburg
- Kontaktdaten:
@sma: Mit http://trac.pylucid.net/changeset/2320 habe ich eine Abgewandelte Form deines Beispiels in PyLucid eingebaut.
In meiner Variante kann man Tags angeben, in denen nichts geändert werden darf. Das ist wichtig, denn in <a href="foo">bar</a> darf "bar" nicht ersetzt werden. Denn schließlich füge ich ja links zum Lexicon ein.
Hier ein Beispiel:
Raus kommt, das:
'<html><p><a href="Foo=Bar"><strong>Foo</strong> Bar</a>*FOO* *BAR*</p></html>'
Sourcecode von SubHtml ist hier: http://trac.pylucid.net/browser/branche ... ub_html.py
Noch was zu verbessern/optimieren?
In meiner Variante kann man Tags angeben, in denen nichts geändert werden darf. Das ist wichtig, denn in <a href="foo">bar</a> darf "bar" nicht ersetzt werden. Denn schließlich füge ich ja links zum Lexicon ein.
Hier ein Beispiel:
Code: Alles auswählen
class LexiconData(dict):
def __call__(self, word_lower, word):
return "*%s*" % word.upper()
lexicon_data = LexiconData({"foo": None, "bar": None})
s = SubHtml(lexicon_data, skip_tags=["a"])
s.process('<html><p><a href="Foo=Bar"><strong>Foo</strong> Bar</a>Foo Bar</p></html>')
'<html><p><a href="Foo=Bar"><strong>Foo</strong> Bar</a>*FOO* *BAR*</p></html>'
Sourcecode von SubHtml ist hier: http://trac.pylucid.net/browser/branche ... ub_html.py
Code: Alles auswählen
import re
SUB_HTML_RE = re.compile(r"(?u)<(\w+)[^>]*>|(\w+)|</(\w+)>")
class SubHtml(object):
def __init__(self, lexicon_data, skip_tags=[]):
# forming a dict from the skip_tags list, for faster lookup
self.skip_tags = dict([(tag.lower(), None) for tag in skip_tags])
self.lexicon_data = lexicon_data
self.in_skip_tag = None
def sub(self, m):
if self.in_skip_tag: # We are in a skip_tags
close_tag = m.group(3)
if close_tag == self.in_skip_tag: # The last skip_tag was closed
self.in_skip_tag = None
return m.group()
tag = m.group(1) # Open html tag
if tag:
if tag.lower() in self.skip_tags:
self.in_skip_tag = tag
return m.group()
word = m.group(2) # A word from the text
if word:
word_lower = word.lower()
if word_lower in self.lexicon_data:
return self.lexicon_data(word_lower, word)
return m.group()
def process(self, html):
return SUB_HTML_RE.sub(self.sub, html)
Ich frage mich nur, wieviele Räder du schon erfunden hast.jens hat geschrieben:Was soll das denn jetzt wieder heißen?
Ständig, und diesmal übertreibe ich nicht, baust du Dinge für PyLucid neu, die es schon längst gibt. Du würdest vermutlich auch eher ne Suchmaschine selbst baun bevor du z.B. Xapian einbindest.
Abhängigkeiten mögen zwar manchmal etwas nervig sein, aber _bitte_ nutz doch etwas mehr fertigen und getesteten Code! Wenn du schon Django als Abhängigkeit hast, dann mach Beatiful Soup den Braten echt nicht fett.
Ich würd gern PyLucid gut finden, aber diese Einstellung von dir verdirbt es mir.