qr// question

M

Matija Papec

How can one know the difference between $arr[0] and $arr[1]?

eg.
my @arr = ('^match') x 2;
$_ = qr/$_/ for $arr[0];

I wouldn't want to do $_ = qr/$_/ twice on same regex (I guess it's time
consuming?)
 
J

John W. Krahn

Matija said:
How can one know the difference between $arr[0] and $arr[1]?

Use 'eq' or '==' to compare them?

eg.
my @arr = ('^match') x 2;

In this instance the contents of $arr[0] and $arr[1] are exactly the
same.

$_ = qr/$_/ for $arr[0];

I wouldn't want to do $_ = qr/$_/ twice on same regex (I guess it's time
consuming?)

What do you REALLY want to do?


John
 
M

Matija Papec

my @arr = ('^match') x 2;

In this instance the contents of $arr[0] and $arr[1] are exactly the
same.

Yes, but after below line they /somehow/ aren't.
$_ = qr/$_/ for $arr[0];

I wouldn't want to do $_ = qr/$_/ twice on same regex (I guess it's time
consuming?)

What do you REALLY want to do?

I want hash/array of regexes but don't want to instantly compile them
all. I would like to compile them only when some particular is needed
and that "some particular" may be used more then once for matching,
while some regexes may not be used at all. If regex compiling is
significantly time consuming then this matters.
 
S

Sam Holden

my @arr = ('^match') x 2;

In this instance the contents of $arr[0] and $arr[1] are exactly the
same.

Yes, but after below line they /somehow/ aren't.
$_ = qr/$_/ for $arr[0];

I wouldn't want to do $_ = qr/$_/ twice on same regex (I guess it's time
consuming?)

What do you REALLY want to do?

I want hash/array of regexes but don't want to instantly compile them
all. I would like to compile them only when some particular is needed
and that "some particular" may be used more then once for matching,
while some regexes may not be used at all. If regex compiling is
significantly time consuming then this matters.

Something like:

use Memoize;
memoize('to_regex');
sub to_regex {
return qr/$_[0]/;
}

or

my %regexes;
sub to_regex {
$regexes{$_[0]} = qr/$_[0]/ unless exists $regexes{$_[0]};
return $regexes{$_[0]};
}

And then when you want to match use

$re = to_regex($string_of_regex);

to get the regex for that string.

Or with an array (or hash with tr/[]/{}/ ) of regexes you could do:

$arr[$index] = qr/$arr[$index]/ unless ref $arr[$index];

Before using $arr[$index] as a regex.
 
A

Anno Siegel

Matija Papec said:
my @arr = ('^match') x 2;

In this instance the contents of $arr[0] and $arr[1] are exactly the
same.

Yes, but after below line they /somehow/ aren't.
$_ = qr/$_/ for $arr[0];

I wouldn't want to do $_ = qr/$_/ twice on same regex (I guess it's time
consuming?)

What do you REALLY want to do?

I want hash/array of regexes but don't want to instantly compile them
all. I would like to compile them only when some particular is needed
and that "some particular" may be used more then once for matching,
while some regexes may not be used at all. If regex compiling is
significantly time consuming then this matters.

Access the regexes through this routine:

sub to_regex {
ref $_[ 0] ? $_[ 0] : $_[ 0] = qr/$_[0]/;
}

Strings will successively be turned into regexes on first use.

Anno
 
B

Brian McCauley

Matija Papec said:
my @arr = ('^match') x 2;

In this instance the contents of $arr[0] and $arr[1] are exactly the
same.

Yes, but after below line they /somehow/ aren't.
$_ = qr/$_/ for $arr[0];

I wouldn't want to do $_ = qr/$_/ twice on same regex (I guess it's time
consuming?)

What do you REALLY want to do?

I want hash/array of regexes but don't want to instantly compile them
all. I would like to compile them only when some particular is needed
and that "some particular" may be used more then once for matching,
while some regexes may not be used at all. If regex compiling is
significantly time consuming then this matters.

And if it isn't then it doesn't.
Access the regexes through this routine:

sub to_regex {
ref $_[ 0] ? $_[ 0] : $_[ 0] = qr/$_[0]/;
}

The text and the subroutine invocation are probably more expensive than the
qr//.

#!/usr/bin/perl
use strict;
use warnings;
use Benchmark;

sub to_regex {
ref $_[ 0] ? $_[ 0] : $_[ 0] = qr/$_[0]/;
}

timethese 10 => {
to_regex => sub {
my $q = q/x..........[yz]+[[:upper:]]*z(?=r)/;
$q = to_regex $q for 0..100000;
},
qr => sub {
my $q = q/x..........[yz]+[[:upper:]]*z(?=r)/;
$q = qr/$q/ for 0..100000;
},
};
__END__

Benchmark: timing 10 iterations of qr, to_regex...
qr: 4 wallclock secs ( 3.52 usr + 0.00 sys = 3.52 CPU) @ 2.84/s (n=10)
to_regex: 6 wallclock secs ( 6.91 usr + 0.00 sys = 6.91 CPU) @ 1.45/s (n=10)


--
\\ ( )
. _\\__[oo
.__/ \\ /\@
. l___\\
# ll l\\
###LL LL\\
 
A

Anno Siegel

Brian McCauley said:
Matija Papec said:
my @arr = ('^match') x 2;

In this instance the contents of $arr[0] and $arr[1] are exactly the
same.

Yes, but after below line they /somehow/ aren't.

$_ = qr/$_/ for $arr[0];

I wouldn't want to do $_ = qr/$_/ twice on same regex (I guess it's time
consuming?)

What do you REALLY want to do?

I want hash/array of regexes but don't want to instantly compile them
all. I would like to compile them only when some particular is needed
and that "some particular" may be used more then once for matching,
while some regexes may not be used at all. If regex compiling is
significantly time consuming then this matters.

And if it isn't then it doesn't.
Access the regexes through this routine:

sub to_regex {
ref $_[ 0] ? $_[ 0] : $_[ 0] = qr/$_[0]/;
}

The text and the subroutine invocation are probably more expensive than the
qr//.

Regex compilation *is* rather expensive. The real reason is that /$re/
doesn't compile the regex again when $re is a single qr//-quoted value.
That would explain your benchmarks. It also makes this a rather futile
exercise.

[snip benchmark]

Anno
 
J

Jeff 'japhy' Pinyan

Access the regexes through this routine:

sub to_regex {
ref $_[ 0] ? $_[ 0] : $_[ 0] = qr/$_[0]/;
}

Strings will successively be turned into regexes on first use.

.... and every time after that. = binds more loosely than ?:

perlmonk:~ $ perl -MO=Deparse,-p -e 'ref $a ? $a : $a = $b'
((ref($a) ? $a : $a) = $b);

It's the same trap as $cond ? $a = $b : $a = $c, which some people use
instead of $a = ($cond ? $b : $c), but always sets $a to $c.
 
M

Matija Papec

X-Ftn-To: Anno Siegel

and that "some particular" may be used more then once for matching,
while some regexes may not be used at all. If regex compiling is
significantly time consuming then this matters.

Access the regexes through this routine:

sub to_regex {
ref $_[ 0] ? $_[ 0] : $_[ 0] = qr/$_[0]/;
}

Strings will successively be turned into regexes on first use.

Tnx, so ref knows all about them! :) Unfortunately perldoc isn't so
informative. :!
 
A

Anno Siegel

Jeff 'japhy' Pinyan said:
Access the regexes through this routine:

sub to_regex {
ref $_[ 0] ? $_[ 0] : $_[ 0] = qr/$_[0]/;
}

Strings will successively be turned into regexes on first use.

... and every time after that. = binds more loosely than ?:

Oh, right. Thanks for catching that. Parentheses around the assignment
would fix it, but, as noted in another branch of the thread, it doesn't
save on regex compilation either way: qr// (well, the regex compiler itself)
already does that.

Anno
 
A

Anno Siegel

Matija Papec said:
X-Ftn-To: Anno Siegel

and that "some particular" may be used more then once for matching,
while some regexes may not be used at all. If regex compiling is
significantly time consuming then this matters.

Access the regexes through this routine:

sub to_regex {
ref $_[ 0] ? $_[ 0] : $_[ 0] = qr/$_[0]/;
}

Strings will successively be turned into regexes on first use.

Tnx, so ref knows all about them! :) Unfortunately perldoc isn't so
informative. :!

You can think of qr/.../ values as objects of class Regexp, which has
stringification overloaded. That describes most of their behavior, though
things aren't really that simple.

perl -Moverload -le'print "yup" if overload::Overloaded( qr//)'

prints nothing.

Anno
 
M

Matija Papec

X-Ftn-To: Sam Holden

my %regexes;
sub to_regex {
$regexes{$_[0]} = qr/$_[0]/ unless exists $regexes{$_[0]};
return $regexes{$_[0]};
}

And then when you want to match use

$re = to_regex($string_of_regex);

to get the regex for that string.

Or with an array (or hash with tr/[]/{}/ ) of regexes you could do:

$arr[$index] = qr/$arr[$index]/ unless ref $arr[$index];

Before using $arr[$index] as a regex.

Tnx, last one looks most promising as it doesn't use any additional
variables.
 
A

Anno Siegel

John W. Krahn said:
Can I quote you on that? :)

You'd be quoting Larry Wall, more or less, or at least some edition of
the Camel. It wasn't about Perl in general, but, I think it assignment
in various contexts that he said that.

Anno
 

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
474,257
Messages
2,571,031
Members
48,768
Latest member
first4landlord

Latest Threads

Top