Schrift
Wiki:Tipp zum Debugging: use Data::Dumper; local $Data::Dumper::Useqq = 1; print Dumper \@var;
[thread]439[/thread]

Suche nach zwei Begriffen

Leser: 1


<< >> 10 Einträge, 1 Seite
Gast Gast
 2005-02-20 21:50
#4439 #4439
Ich benutze eine Textdatei als Datenbank. Nun möchte ich in ein Suchfeld zwei Begriffe (oder auch mehr) eingeben. Es sollen aber nur Datensätze/Zeilen ausgeworfen werden, die genau diese beiden Begriffe (oder mehr) enthalten.

Wie ich nach einer Zeichenkette suche, weiß ich.

Narim
betterworld
 2005-02-20 22:09
#4440 #4440
User since
2003-08-21
2614 Artikel
ModeratorIn

user image
Also, Du weisst, wie Du Zeilen ausgibst, die eine Zeichenkette beinhalten. Dann musst Du ja nur noch wissen, was der "and"-Operator bzw der "&&"-Operator macht. Gib mal perldoc perlop in der Shell ein, da steht das.\n\n

<!--EDIT|betterworld|1108930225-->
Taulmarill
 2005-02-21 11:42
#4441 #4441
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
so in etwa sollte das aussehen, code ist ungetestet:

Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
use strict;
use warnings;

my @such = qw/foo bar/; # zwei suchbegriffe
open FILE, "</meine/datei.txt" or die $!;
while ( my $zeile = <FILE> ) {
if ( $zeile =~ /${such[0]}/ and $zeile =~ /${such[1]}/ ) {
print $zeile;
}
}
close FILE;
\n\n

<!--EDIT|Taulmarill|1108978982-->
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
Gast Gast
 2005-02-21 17:29
#4442 #4442
Ohne regulären Ausdruck mit beliebiger Anzahl Wörtern mit UND Verknüpfung:
Code: (dl )
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
#!/usr/bin/perl
use warnings;
use strict;

my @searched = qw( die ist );

line:
while ( my $l = <DATA> ) {
for( @searched )
{ next line unless index($l, $_) + 1 }
print $l;
}

# Das hier gehört nach _ _ DATA _ _, das Forum killt das aber.
Das ist die erste Zeile.
Dies ist die zweite Zeile.
Hier kommt Nummer drei.
\n\n

<!--EDIT|phaylon|1108999890-->
Taulmarill
 2005-02-21 17:48
#4443 #4443
User since
2004-02-19
1750 Artikel
BenutzerIn

user image
hm, index() sollte hier schneller sein, da es spezialisierter ist.
ich werd das mal nachher benchmarken wenn ich zeit habe.
$_=unpack"B*",~pack"H*",$_ and y&1|0& |#&&print"$_\n"for@.=qw BFA2F7C39139F45F78
0A28104594444504400 0A2F107D54447DE7800 0A2110453444450500 73CF1045138445F4800 0
F3EF2044E3D17DE 8A08A0451412411 F3CF207DF41C79E 820A20451412414 83E93C4513D17D2B
Gast Gast
 2005-02-21 18:40
#4444 #4444
[quote=Taulmarill,21.02.2005, 16:48]hm, index() sollte hier schneller sein, da es spezialisierter ist.
ich werd das mal nachher benchmarken wenn ich zeit habe.[/quote]
Ich hab das mal durch Benchmark gejagt. Den RegEx-Code hab' ich modifiziert um eine variable Anzahl an Suchbegriffen per AND zu ermöglichen:
Code: (dl )
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
#!/usr/bin/perl
use warnings;
use strict;

use Benchmark qw(:all);
my @searched = qw( Eins Dies );
my @lines = <DATA>;

cmpthese( 1_000_000, {
'index' => sub { by_index( \@searched, \@lines ) },
'w_reg' => sub { by_walked_regex( \@searched, \@lines ) },
});


sub by_index {
my @such = @{ $_[0] };
my @lin = @{ $_[1] };

line:
while ( my $l = shift @lin ) {
for( @such )
{ next line unless index( $l, $_ ) + 1 }
print STDERR "i $l";
}
}

sub by_walked_regex {
my @such = @{ $_[0] };
my @lin = @{ $_[1] };

line:
while ( my $l = shift @lin ) {
for( @such )
{ next line unless $l =~ /$_/ }
print STDERR "wr $l";
}
}


Dies ist Zeile Eins, wird gefunden.
Dies ist Zeile Zwei, wird nicht gefunden.
Dies ist Zeile Drei, wird auch nicht gefunden.

Das Ergebnis:
Code: (dl )
1
2
3
4
5
phaylon@hamlett:~/ptests> perl search_bench.pl 2>/dev/null
Rate w_reg index
w_reg 13687/s -- -66%
index 40145/s 193% --
phaylon@hamlett:~/ptests>

hth
ptk
 2005-02-21 20:41
#4445 #4445
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Welches Perl? Mit 5.8.0 und 5.8.6 (Linux) sind beide Variante gleich schnell (1% Unterschied).
Gast Gast
 2005-02-21 21:26
#4446 #4446
Code: (dl )
This is perl, v5.8.3 built for i586-linux-thread-multi

Code: (dl )
1
2
3
4
phaylon@hamlett:~/ptests> cat /proc/cpuinfo
...
cpu MHz : 2994.546
cache size : 1024 KB

Hier noch ein Durchlauf mit timethese statt cmpthese:
Code: (dl )
1
2
3
4
phaylon@hamlett:~/ptests> perl search_bench.pl 2>/dev/null
Benchmark: timing 1000000 iterations of index, w_reg...
index: 25 wallclock secs (24.36 usr + 0.62 sys = 24.98 CPU) @ 40032.03/s (n=1000000)
w_reg: 74 wallclock secs (72.47 usr + 1.10 sys = 73.57 CPU) @ 13592.50/s (n=1000000)

Ideen? :D
ptk
 2005-02-21 21:32
#4447 #4447
User since
2003-11-28
3645 Artikel
ModeratorIn
[default_avatar]
Alles klar... als Neuling bist du ueber den _ _ BLA _ _ -Bug in diesem Forum gestolpert. _ _ DATA _ _ und _ _ END _ _ werden stillschweigend geloescht, wenn sie richtig geschrieben werden. Mit dem korrekten DATA-Block bekomme ich auch deine Ergebnisse.
Gast Gast
 2005-02-22 00:04
#4448 #4448
Argh. Nein, ich hab's nur beim zweiten mal wieder verdrängt ..
<< >> 10 Einträge, 1 Seite



View all threads created 2005-02-20 21:50.