Avatar billede Boddicker Seniormester
23. januar 2000 - 14:51 Der er 7 kommentarer og
1 løsning

Forkert søge-mekanisme

Jeg bruger nedenstående søgemaskine-script på min hjemmeside. Problemet er, at den ikke søger i hele ord, men blot i dele af ord. F.eks. hvis man søger på ordet "ass" for man et hit fordi det indgår i ordet "passe". Jeg vil have det sådan, at den KUN finder ordet ass, hvis de virkelig står på en given side og IKKE blot indgår i et ord. Scriptet ser således ud:

#!/usr/bin/perl

    require "vars.pl";
   
    require "layout.pl";

    unless ( $ENV{'QUERY_STRING'} ) { print "Location: $search_url\n\n"; exit; }

    &get_form;

    &set_vars;   

    &search_index;
   
    &print_results;

    exit;
   

##############################################################################
# Sub-Routines

sub print_results
{
    print "Content-type: text/html\n\n";

    my $foundcount = @FOUND;
    my $terms = '';

    foreach my $term ( reverse sort @TERMS_MAX )
    {
        $terms = $term . ',' . $terms;
    }

    chop($terms);

    my $term = @TERMS_MAX;


    # Next and Previous inner-workings #############################

    if ( $FORM{'pos'} )
    {
        $pos = abs($FORM{'pos'});
        if ( $pos ne $FORM{'pos'} ) { $pos = 0; }
    }
    else { $pos = 0; }
   
    $nextpos = $pos + $links_in_page;
    if ( $nextpos > $foundcount ) { $nextpos = $foundcount }
    $prevpos = $pos - $links_in_page;
    if ( $prevpos > $foundcount ) { $prevpos = $foundcount - $links_in_page }
    if ( $prevpos < 0 ) { $prevpos = 0 }

    my $nexturl = "$cgi_url?terms=$qsterms1&pos=$nextpos&boolean=$boolean&case=$case";
    my $prevurl = "$cgi_url?terms=$qsterms1&pos=$prevpos&boolean=$boolean&case=$case";
    my $nextprev = '';

    my $usenext = 0;
    my $useprev = 0;

    if ( $nextpos ne $foundcount ) { $usenext = 1 }
    if ( $prevpos eq 0 && $pos ne 0 ) { $useprev = 1 }
    if ( $prevpos ne 0 ) { $useprev = 1 }
   
    if ( $usenext eq 0 && $useprev eq 0 ) { $nextprev = $nnext_nprev }
    elsif ( $usenext eq 1 && $useprev eq 1 ) { $nextprev = $ynext_yprev }
    elsif ( $usenext eq 1 && $useprev eq 0 ) { $nextprev = $ynext_nprev }
    elsif ( $usenext eq 0 && $useprev eq 1 ) { $nextprev = $nnext_yprev }

    $nextprev =~ s/%nexturl%/$nexturl/ig;
    $nextprev =~ s/%prevurl%/$prevurl/ig;
   
    if ( $links_in_page eq 0 ) { $nextprev = '' }

    my $posmin = $pos + 1;

    if ( $pos > $foundcount )
    {
            $posmin = 0;
            $nextpos = 0;
    }
    if ( $posmin ne 0 && $nextpos eq 0 ) { $posmin = 0 }

    ################################################################

   
    print $doc_header;

    $doc_content =~ s/%matches%/$foundcount/ig;
    $doc_content =~ s/%boolean%/$boolean/ig;
    $doc_content =~ s/%case%/$case/ig;
    $doc_content =~ s/%terms.show%/$terms/ig;
    $doc_content =~ s/%terms.qs%/$FORM{'terms'}/ig;
    $doc_content =~ s/%terms.count%/$term/ig;

    if ( $foundcount ne 0 ) { $doc_content =~ s/%next-previous%/$nextprev/ig; }
    else { $doc_content =~ s/%next-previous%//ig; }

    $doc_content =~ s/%pos.min%/$posmin/ig;
    $doc_content =~ s/%pos.max%/$nextpos/ig;

    if ( $foundcount eq 0 )
    {
        print $doc_nomatches;
    }
    else
    {
        print $doc_content;

        my $countpos = 0;
        foreach my $line ( reverse sort @FOUND )
        {
            ($perc,$fileurl,$filename,$shortname,$meta_mts,$meta_1,$meta_2,$meta_3,$title,$body) = split("\t",$line);

            if ( $percents eq 0 ) { $perc = '' }

            my $send = '';

            if ( $title && $meta_1 ) { $send = $result_ymeta1_ytitle }
            if ( !$title && $meta_1 ) { $send = $result_ymeta1_ntitle }
            if ( $title && !$meta_1 ) { $send = $result_nmeta1_ytitle }
            if ( !$title && !$meta_1 ) { $send = $result_nmeta1_ntitle }

            $send =~ s/%percent%/$perc/ig;
            $send =~ s/%url%/$fileurl/ig;
            $send =~ s/%title%/$title/ig;
            $send =~ s/%meta_1%/$meta_1/ig;
            $send =~ s/%tab%/\t/ig;
            $send =~ s/%newline%/\n/ig;
            $send =~ s/%mts%/$meta_mts/ig;
            $send =~ s/%filename%/$filename/ig;
            $send =~ s/%mts%/$meta_mts/ig;
            $send =~ s/%terms.qs%/$qsterms/ig;

            ++$countpos;

            if ( $links_in_page ne 0 )
            {
                if ( $countpos > $pos )
                {
                    print $send;
                }
                if ( $countpos eq $pos + $links_in_page ) { last }
            }
            else { print $send }
        }
    }

    if ( $foundcount ne 0 ) { $doc_footer =~ s/%next-previous%/$nextprev/ig; }
    else { $doc_footer =~ s/%next-previous%//ig; }

    print $doc_footer;
}

sub search_index
{
    open(FILE,$index_db) || &script_error('Error Reading DB');
    my @file = <FILE>;
    close(FILE);

    my $linecount = @file;
    if ( $linecount eq 0 ) { &script_error('Empty DB') }

    # Begin Variable Setting #################################

    my $termcount = @TERMS_MIN;

    my $areas = 0;
       
    if ( $meta_tag_1 ) { $areas = $areas + $meta1_weight }
    if ( $meta_tag_2 ) { $areas = $areas + $meta2_weight }
    if ( $meta_tag_3 ) { $areas = $areas + $meta3_weight }
    if ( $index_title eq 1 ) { $areas = $areas + $title_weight }
    if ( $index_body eq 1 ) { $areas = $areas + $body_weight }

    if ( $areas eq 0 ) { &script_error('No Searchable Tags Indexed') }

    $areas = $areas * $termcount;

    # End Variable Setting ###################################

    foreach my $line ( @file )
    {
        chomp($line);
        ($fileurl,$filename,$shortname,$meta_mts,$meta_1,$meta_2,$meta_3,$title,$body) = split("\t",$line);

        # Variable Setting #######################################

        my $area1 = 0;
        my $area2 = 0;
        my $area3 = 0;
        my $area4 = 0;
        my $area5 = 0;
        my $perc = 0;
        my $foundterms = 0;

        # Begin searching ########################################

        foreach my $cursearch ( @TERMS_MIN )
        {

            my $foundterm = 0;

            if ( $case eq 'Insensitive' )
            {

                if ( $meta_1 =~ /$cursearch/i )
                {
                    ++$area1;
                    if ( $foundterm eq 0 ) { $foundterm = 1 }
                }

                if ( $meta_2 =~ /$cursearch/i )
                {
                    ++$area2;
                    if ( $foundterm eq 0 ) { $foundterm = 1 }
                }

                if ( $meta_3 =~ /$cursearch/i )
                {
                    ++$area3;
                    if ( $foundterm eq 0 ) { $foundterm = 1 }
                }

                if ( $title =~ /$cursearch/i )
                {
                    ++$area4;
                    if ( $foundterm eq 0 ) { $foundterm = 1 }
                }

                if ( $body =~ /$cursearch/i )
                {
                    ++$area5;
                    if ( $foundterm eq 0 ) { $foundterm = 1 }
                }

                if ( $foundterm eq 1 ) { ++$foundterms }
            }
            else
            {
                if ( $meta_1 =~ /$cursearch/ )
                {
                    ++$area1;
                    if ( $foundterm eq 0 ) { $foundterm = 1 }
                }

                if ( $meta_2 =~ /$cursearch/ )
                {
                    ++$area2;
                    if ( $foundterm eq 0 ) { $foundterm = 1 }
                }

                if ( $meta_3 =~ /$cursearch/ )
                {
                    ++$area3;
                    if ( $foundterm eq 0 ) { $foundterm = 1 }
                }

                if ( $title =~ /$cursearch/ )
                {
                    ++$area4;
                    if ( $foundterm eq 0 ) { $foundterm = 1 }
                }

                if ( $body =~ /$cursearch/ )
                {
                    ++$area5;
                    if ( $foundterm eq 0 ) { $foundterm = 1 }
                }

                if ( $foundterm eq 1 ) { ++$foundterms }
            }

        }

        if ( $meta_tag_1 ) { $area1 = $area1 * $meta1_weight }
        if ( $meta_tag_2 ) { $area2 = $area2 * $meta2_weight }
        if ( $meta_tag_3 ) { $area3 = $area3 * $meta3_weight }
        if ( $index_title eq 1 ) { $area4 = $area4 * $title_weight }
        if ( $index_body eq 1 ) { $area5 = $area5 * $body_weight }

        $perc = $area1 + $area2 + $area3 + $area4 + $area5;
        $perc = int(($area1 + $area2 + $area3 + $area4 + $area5) / $areas * 100);

        if ( length($perc) eq 1 && $perc > 0 ) { $perc = '0' . $perc }
        if ( $perc > 100 ) { $perc = '100' }

        if ( $boolean eq 'OR' && $perc ne 0 ) { push(@FOUND,"$perc%\t$line") }
        if ( $boolean eq 'AND' && $foundterms eq $termcount && $perc ne 0 ) { push(@FOUND,"$perc%\t$line") }

        # End Searching ##########################################

    }
}

sub script_error
{
    # No Valid Terms
    # Error Reading DB
    # Empty DB
    # No Searchable Tags Indexed

    print "Content-type: text/html\n\n";

    print $doc_header;

    if ( $_[0] eq 'No Valid Terms' )
    {
        print $doc_noterms
    }
    else
    {
        $doc_error =~ s/%error%/$_[0]/ig;
        print $doc_error;
    }

    $doc_footer =~ s/%next-previous%//ig;
    print $doc_footer;
    exit;
}

sub set_vars
{

    @TERMS_MAX = split(/\s+/,$FORM{'terms'});

    my @IGNORE_CHAR = split(/\s+/,$ignore_chars);

    foreach my $CHAR ( @IGNORE_CHAR )
    {
        if ( $CHAR = "\s" ) { next }
        $FORM{'terms'} =~ s/$CHAR//g;
    }

    my @TERMS_TEMP = split(/\s+/,$FORM{'terms'});

    foreach my $term ( @TERMS_TEMP )
    {
        #$term =~ s/\W//g;
        if ( $ignore_words =~ / $term /i || $term eq '' || length($term) < $min_word_size ) { next; }
        else { push(@TERMS_MIN,$term) }
    }

    my $termcount_min = @TERMS_MIN;

    if ( $termcount_min eq 0 ) { &script_error('No Valid Terms') }


    if ( $FORM{'boolean'} eq 'OR' or $FORM{'boolean'} eq 'AND' ) { $boolean = $FORM{'boolean'} }
    else
    {
        if ( $def_boolean eq 1 ) { $boolean = 'AND' }
        else { $boolean = 'OR' }
    }


    if ( $FORM{'case'} eq 'Sensitive' or $FORM{'case'} eq 'Insensitive' ) { $case = $FORM{'case'} }
    else
    {
        if ( $def_case eq 1 ) { $case = 'Sensitive' }
        else { $case = 'Insensitive' }
    }

}

sub get_form
{
    $buffer = $ENV{'QUERY_STRING'};

    @pairs = split(/&/, $buffer);

    foreach $pair (@pairs)
    {
        ($name, $value) = split(/=/, $pair);

        if ( $name eq 'terms' ) { $qsterms1 = $value }

        $value =~ tr/+/ /;
        $value =~ s/%([a-fA-F0-9][a-fA-F0-9])/pack("C", hex($1))/eg;

        if ( $name eq 'terms' ) { $qsterms = $value }

        $FORM{$name} = $value;
    }
}

# End of sub-routines. End of script. All done.
##############################################################################
Avatar billede erikjacobsen Ekspert
23. januar 2000 - 16:13 #1
I f.eks.

    if ( $body =~ /$cursearch/i )

skriver du

  if ( $body =~ /\W$cursearch\W/i )

for at angive at dit søgeord skal være omgivet af "ikke-ords-tegn".
Avatar billede Boddicker Seniormester
23. januar 2000 - 16:56 #2
Alletiders! Mange tak! :)
Avatar billede erikjacobsen Ekspert
23. januar 2000 - 17:53 #3
En lill ekstra kommentar - selv om jeg har fået min belønning... :

\W svarer til [^a-zA-Z_0-9], altså ingen af de nævnte tegn. Hvis du
har flere slags bogstaver i dine ord, og æ, ø og å falder mig umiddelbart
ind, må du gøre det "manuelt":

      if ( $body =~ /[^a-zA-Z_0-9æøåÆØÅ]$cursearch[^a-zA-Z_0-9æøåÆØÅ]/i )

(Jeg elsker regulære udtryk...)

Avatar billede Boddicker Seniormester
23. januar 2000 - 18:05 #4
Takker endnu engang!

Du skulle vel ikke have et bud på et andet spørgsmål jeg har? Det drejer sig om:
http://www.eksperten.dk/spm.asp?id=10287
Avatar billede erikjacobsen Ekspert
23. januar 2000 - 19:07 #5
Tak for tilliden... Jeg har set spørgsmålet, men har ingen svar - udover
at jeg også oplever det, andre steder, og føler at det må være
netværksproblemer, ikke script-problemer.

Og til dit cookie-spørgsmål: Jeg ved "alt" om cookies, bare ikke
lige i Perl. Jeg checkede min litteratur, men fandt ikke andet end
(in)direkte manipulation med HTTP-headeren. Spændende - men jeg
har ikke erfaring i det.
Avatar billede Boddicker Seniormester
24. januar 2000 - 08:24 #6
Okay! :)

Well... jeg kan også bruge cookies i PHP i stedet, hvis det var bedre? :)
Avatar billede erikjacobsen Ekspert
24. januar 2000 - 08:30 #7
Det er supernemt i PHP. Bare spørg
i PHP-gruppen.
Avatar billede Boddicker Seniormester
24. januar 2000 - 09:07 #8
I will! :)
Avatar billede Ny bruger Nybegynder

Din løsning...

Tilladte BB-code-tags: [b]fed[/b] [i]kursiv[/i] [u]understreget[/u] Web- og emailadresser omdannes automatisk til links. Der sættes "nofollow" på alle links.

Loading billede Opret Preview
Kategori
Kurser inden for grundlæggende programmering

Log ind eller opret profil

Hov!

For at kunne deltage på Computerworld Eksperten skal du være logget ind.

Det er heldigvis nemt at oprette en bruger: Det tager to minutter og du kan vælge at bruge enten e-mail, Facebook eller Google som login.

Du kan også logge ind via nedenstående tjenester