matching two strings

G

Guy

In a previous post, I said that I wanted to search through lines of text, to
see if any of them contained keywords that the user would submit. Using the
"|" character, I could use the m// operator to see if a line of text
contained any of the keywords.

Is there a way to verify if a line of text contains all of the keywords?

Thanks,
Guy
 
G

Guy

Ben Morrow said:
Sometimes simple is better:

/one/ && /two/ && /three/

If you have a list of keywords, you can iterate over it with grep:

not grep $string !~ $_, qr/one/, qr/two/, qr/three/

(using the fact that 'a AND b' is equivalent to 'NOT(NOT(a) OR NOT(b))')

Pretty clever!
or with List::MoreUtils::all, which will be more efficient:

use List::MoreUtils qw/all/;

all { $string =~ $_ } qr/one/, qr/two/, qr/three/

If you *really* want a single regex, you can use something like

/^(?=.*one)(?=.*two)(?=.*three)/

but I wouldn't recommend it.

Ben

Thanks,
Guy
 
P

Peter Makholm

Ben Morrow said:
(using the fact that 'a AND b' is equivalent to 'NOT(NOT(a) OR NOT(b))')
or with List::MoreUtils::all, which will be more efficient:

use List::MoreUtils qw/all/;

all { $string =~ $_ } qr/one/, qr/two/, qr/three/

Have you actually benchmarked this or are you just guessing?

When I benchmarked grep vs. any, grep won by being 25% faster on
random indata by avarage, even tough I naivly would have expected any
to win.

But for short list I don't think athe difference is noticable and I
would go for what is most self-documenting.

//Makholm
 
S

Skye Shaw!@#$

In a previous post, I said that I wanted to search through lines of text,to
see if any of them contained keywords that the user would submit.  Using the
"|" character, I could use the m// operator to see if a line of text
contained any of the keywords.

Is there a way to verify if a line of text contains all of the keywords?

[sshaw@localhost perl]$ cat bs.pl
my $line = "she's fast, low class, loves bass and has a big ass";
my @keywords = qw|ass fast|;
print 'Match!' if scalar(grep index($line, $_) != -1, @keywords) ==
@keywords;

[sshaw@localhost perl]$ perl -l bs.pl
Match!

I think I remember reading in the Perl tome (aka its man pages) that
grep() was slow and to never use it (others have pointed this out as
well) so maybe the above would be "better" (i.e. uglier) with a for
().

-Skye
 
S

Skye Shaw!@#$

I think I remember reading in the Perl tome (aka its man pages) that
grep() was slow and to never use it

Well, that's a little harsh.

It seems that I was referring to a combination of `perldoc -q grep`,
where it advises one not to use grep() like for() and `perldoc -q 'in
a list or array'`, 2nd to last paragraph.

-Skye
 
S

sln

I'm not really sure what is happening and unfortunatly I didn't seem
to keep my benchmarking code. I wrote about it at

http://peter.makholm.net/2009/05/26/benchmarking-is-hard/

I might have used Jason Switchers code modified to only use one
needle and array.

//Makholm

I don't see how grep is faster than anything.

-sln

---------------------------
use strict;
use warnings;
use Benchmark ':hireswallclock';

my @rxs = (qr/one/, qr/two/, qr/three/);
my @strings =
# (
# 'two three one',
# 'one three ',
# 'three two',
# 'three',
# ' '
# );
(
'one two three',
'one two three',
'one two three',
'one two three',
);
my ($pass,$val,$string,$rxs,$t0,$t1,$tdif);


$t0 = new Benchmark;
for (1..10_000) {
foreach $string (@strings) {
if ( not $val = grep $string !~ $_, @rxs)
{
# print "grep !$val = yes\n";
} else {
# print "grep !$val = no\n";
}
}
}
$t1 = new Benchmark;
print "grep code took:",timestr( timediff($t1, $t0) ),"\n";


$t0 = new Benchmark;
for (1..10_000) {
STRING:
for (@strings) {
for $rxs (@rxs) {
if ( !/$rxs/)
{
# print "var && no\n";
next STRING;
}
}
# print "var && yes\n";
}
}

$t1 = new Benchmark;
print "(1)&& code took:",timestr( timediff($t1, $t0) ),"\n";

$t0 = new Benchmark;
for (1..10_000) {
for (@strings) {
if ( /one/ && /two/ && /three/)
{
# print "const && yes\n";
} else {
# print "const && no\n";
}

}
}
$t1 = new Benchmark;
print "(2)&& code took:",timestr( timediff($t1, $t0) ),"\n";

__END__
Output:
grep code took:0.207262 wallclock secs ( 0.20 usr + 0.00 sys = 0.20 CPU)
(1)&& code took:0.246479 wallclock secs ( 0.25 usr + 0.00 sys = 0.25 CPU)
(2)&& code took:0.0333102 wallclock secs ( 0.03 usr + 0.00 sys = 0.03 CPU)
 
S

sln

I don't see how grep is faster than anything.

-sln

---------------------------
use strict;
use warnings;
use Benchmark ':hireswallclock';

my @rxs = (qr/one/, qr/two/, qr/three/);
my @strings =
# (
# 'two three one',
# 'one three ',
# 'three two',
# 'three',
# ' '
# );
(
'one two three',
'one two three',
'one two three',
'one two three',
);
my ($pass,$val,$string,$rxs,$t0,$t1,$tdif);


$t0 = new Benchmark;
for (1..10_000) {
foreach $string (@strings) {
if ( not $val = grep $string !~ $_, @rxs)
{
# print "grep !$val = yes\n";
} else {
# print "grep !$val = no\n";
}
}
}
$t1 = new Benchmark;
print "grep code took:",timestr( timediff($t1, $t0) ),"\n";


$t0 = new Benchmark;
for (1..10_000) {
STRING:
for (@strings) {
for $rxs (@rxs) {
if ( !/$rxs/)
{
# print "var && no\n";
next STRING;
}
}
# print "var && yes\n";
}
}

$t1 = new Benchmark;
print "(1)&& code took:",timestr( timediff($t1, $t0) ),"\n";

$t0 = new Benchmark;
for (1..10_000) {
for (@strings) {
if ( /one/ && /two/ && /three/)
{
# print "const && yes\n";
} else {
# print "const && no\n";
}

}
}
$t1 = new Benchmark;
print "(2)&& code took:",timestr( timediff($t1, $t0) ),"\n";

__END__
Output:
grep code took:0.207262 wallclock secs ( 0.20 usr + 0.00 sys = 0.20 CPU)
(1)&& code took:0.246479 wallclock secs ( 0.25 usr + 0.00 sys = 0.25 CPU)
(2)&& code took:0.0333102 wallclock secs ( 0.03 usr + 0.00 sys = 0.03 CPU)

Because grep is oblivous to early, its square like a matrix.

-sln
 
J

John W. Krahn

Because grep is oblivous to early, its square like a matrix.

What range is described by "oblivous to early" (whatever oblivous is)?
How do you get from one to the other and along what route? You are
using the possessive pronoun "its" on what object? And how does that
object possess a "square like a matrix"?



John
 

Ask a Question

Want to reply to this thread or ask your own question?

You'll need to choose a username for the site, which only take a couple of moments. After that, you can post your question and our members will help you out.

Ask a Question

Members online

Forum statistics

Threads
473,773
Messages
2,569,594
Members
45,119
Latest member
IrmaNorcro
Top