Readers: 32
2010-07-11T09:03:04 pqein query parser parst die nutzer-eingabe und liefert dir idealerweise einen baum der bedingungen.
2010-07-19T10:13:58 moritzIch wuerde dir empfehlen, mit rekursiv absteigenden Parsern anzufangen, die sind leicht zu verstehen, und fuer die meisten Aufgaben vollkommen ausreichend.
2010-07-19T12:01:34 moritzEs liegt daran, dass du dich nicht zwischen was fertigem und was selbst gemachtem entscheiden kannst. Oder etwas selbst machen willst, aber keinen Aufwand ins Lernen investieren zu wollen scheinst.
2010-07-19T12:20:48 Styxum die Doku des vorgeschlagenen Moduls zu lesen und wenn noetig auch zu uebersetzen (geht die naechste Uebersetzung vermutlich auch schneller)?
2010-07-19T12:52:25 biancasondern z.B. auch wissen, wie man variable Bedingungen "baut".
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
my $condition = { LOGIC => [ 'OR', { CONDITION => [ 'EQ', 'blabla', ], }, { LOGIC => [ 'AND', { CONDITION => [ 'LIKE', 'foo%', ], }, { CONDITION => [ 'LIKE', '%bar', ], }, ], } ], };
QuoteWas/wie/wo muss ich lesen/machen/einsteigen?
2010-07-19T13:19:18 pqdas könnte sowas sein:
2010-07-19T13:32:58 biancaJa!! So in etwa schwebte mir das vor. Bedingungen in einer Variable speichern.
QuoteWie wendet man das hier gezeigte Beispiel in einem Stringvergleich an?
2010-07-19T13:57:43 pqalso das parsen, für das es ein modul gibt, möchtest du selber machen wegen lernen, und für das "mach aus irgendeiner hash-array-struktur einen textvergleich", für das du noch nicht mal das format angegeben hast, willst du ein fertiges modul?
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78
#!/usr/bin/perl use strict; use warnings; # Prototyp Definition # nur Damit der Code schön ist :-) sub split_text($$); # zu parsender Text my $text="das ist ein Text"; # Parser starten und Ergebnis lesen my @liste=split_text('',$text); # Ergebnis ausgeben print join("|",@liste)."\n"; ######################################################################## ######################################################################## # Rekursive Funktion. sub split_text($$) { # Element das geprüft wurde my $last=shift; # zu prüfender Text my $text=shift; # Es können auch weitere Werte übergeben werden, # wie die verschachtelungstiefe oder Eigenschaften, # aus dem Vorherigen Elemnt, # welches das parsen des Nächsten beeinflusst. # liste mit den gefundenden Elementen my @elements=(); # ist Noch Text zu Parsen? if(length($text)>0) { # Das Zerlegen zusammen mit dem Prüfen ist eine "Regel" # Hier haben wir nur eine, die auch nicht komplex ist # Hier würde das "Top-Bottom" Greifen. # Mit einer Möglichst allgemeinen Regel würde Ein großer Teil "heraus gemommen" # und an weitere Regeln weiter geleitet, # die daraus dann die Gewünschten Informationen holen # Ein spezifischen Teil aus dem zu parsenden Text herausschneiden # Hier ist es ein Zeichen, es kann aber auch mehr sein # Das ganze kann auch eine komplexe Funktion sein my $char=substr($text,0,1,''); # Den gewonnenen Teil auf bestimmte Eigenschaften untersuchen # Hier testen ob es eine Leerzeichen und damit ein "Worttrenner" ist if($char eq ' ') { # Den geparsten Teil Der Liste der gefunden Elemente hinzufügen push(@elements,$last); # Aufräumen # Hier "$last" leeren Damit das Nächte wort darin abgelegt werden kann $last=''; } # Wenn das Zeichen noch zu dem Wort gehört, # an Das bisherige Wort anhängen else { $last.=$char; } # Sich selber mit den veränderten Parametern aufrufen # und das Ergebnis der liste der Gefunden Elemente hinzufügen push(@elements,split_text($last,$text)); } # Es ist nichts mehr zu parsen # ist noch ein geparstes Element vorhanden, # das in Die Liste aufgenommen werden muss? elsif(length($last)) { push(@elements,$last); } # Ergebnis zurückliefern return @elements; }
QuoteIch würde in einer Schleife Zeichen für Zeichen lesen und schauen, ob die Begriffe AND oder OR vorhanden sind.
2010-07-19T13:27:54 biancaAlso das Zerlegen des ganzen Strings in Wörter. Im Großen und Ganzen sieht das aus wie ein @elements=split/ /,$zu_parsender_text.
2010-07-19T13:27:54 biancaHab ich das bis hierher richtig verstanden?
Ein rekursiver Parser ist also nichts weiter als dies?
OK, dann hatte ich mir mehr darunter vorgestellt als es ist.
2010-07-19T13:27:54 biancaWie kommt denn nun das Speichern einer Bedingung ins Spiel?
Der Benutzer gibt ein "das AND Text" und daraus soll die Bedingung "enthält 'das' && enthält 'Text'" entstehen, die ich auf $text anwenden möchte?
1 2 3 4 5 6
if(index($text,"Bedingung 1")) { print "gefunden\n"; } elsif(index($text,"Bedingung 2")) { print "gefunden\n"; } else { print "nicht gefunden\n" }
1 2 3 4 5 6 7 8 9
if(index($text,"Bedingung 1")) { if(index($text,"Bedingung 2")) { print "gefunden\n"; } else { print "nicht gefunden\n" } } else {print "nicht gefunden\n"}
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21
if($struct->[0] eq 'OR') { if(index($text,$struct->[1])) { print "gefunden\n"; } elsif(index($text,$struct->[2])) { print "gefunden\n"; } else { print "nicht gefunden\n" } } elsif($struct->[0] eq 'AND') { if(index($text,$struct->[1])) { if(index($text,$struct->[2])) { print "gefunden\n"; } else { print "nicht gefunden\n" } } else {print "nicht gefunden\n"} }
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69
#!/usr/bin/perl -w use strict; use warnings; use diagnostics; my $userinput = '"schöner" auf'; my $verknuepfung = 1; # 1=OR 2=AND my %dateien = ( # dieser Hash simuliert mehrere ASCII-Dateien die per Schleife eingelesen werden 1 => 'Heute ist ein schöner Tag und die Sonne geht auf', 2 => 'Gestern war ein "schöner" Tag und die Sonne ging unter', 3 => 'foo', 4 => 'bar', 5 => 'Vorvorgestern war auch ein schöner Tag wo die Sonne auf ging', ); my @rueck = stringsuche ('bedingung',$userinput,$verknuepfung); my $code = shift @rueck; my $meld = shift @rueck; print "Rückmeldecode $code - $meld\n"; foreach my $text (values %dateien) { my $ergebnis = stringsuche ('suche',$text,@rueck); print "Untersuche '$text' => " . ($ergebnis ? "Treffer\n" : "\n"); } sub stringsuche { my $action = shift; if ($action eq 'bedingung') { my $userinput = shift; my $verknuepfung = shift; my @return; if ($userinput ne '') { if ($verknuepfung =~ /^[1|2]$/) { @return = (1,'OK'); $return[2] = $verknuepfung; push @return,split / /,$userinput; } else { @return = (0,'Verknüpfung falsch, 1=OR oder 2=AND'); } } else { @return = (0,'Kein Suchbegriff eingegeben'); } return @return; } elsif ($action eq 'suche') { my $text = shift; my @bedingung = @_; my $verknuepfung = shift @bedingung; my $return = 0; if ($verknuepfung eq '1') { foreach my $bed (@bedingung) { if ($text =~ /$bed/) { $return = 1; last; } } } elsif ($verknuepfung eq '2') { my $treffer = 0; foreach my $bed (@bedingung) { my $vergleich = quotemeta $bed; if ($text =~ /$vergleich/) { $treffer ++; } } $return = 1 if $treffer == scalar @bedingung; } return $return; } }