Velocity Reviews

Velocity Reviews (http://www.velocityreviews.com/forums/index.php)
-   Perl Misc (http://www.velocityreviews.com/forums/f67-perl-misc.html)
-   -   using the result of a variable regular expression (http://www.velocityreviews.com/forums/t887783-using-the-result-of-a-variable-regular-expression.html)

leifwessman@hotmail.com 08-26-2004 04:19 PM

using the result of a variable regular expression
 

Hi!

I need to extract a certain value from a text. But the result isn't
always in the variable $1 - it might be in $2, $3, $4 or some other
predefined variable.

Some code to illustrate my problem:

$regexp = "(\d)(\w)(\d)";
$numb = 3; # Means the result I'm looking for is in $3
# I don't know this number, it's submitted
by user
# and may differ

if ($data =~ /$regexp/) {

print $numb; # does not work, prints "3"

# alternative solution that works
# but it's UGLY
if ($numb == 1) {
print $1;
} elsif ($numb == 2) {
print $2;
} elsif ($numb == 3) {
print $3;
}

# is there another way?
}

Thanks for any input!

Leif


Brian McCauley 08-26-2004 04:47 PM

Re: using the result of a variable regular expression
 


leifwessman@hotmail.com wrote:

> I need to extract a certain value from a text. But the result isn't
> always in the variable $1 - it might be in $2, $3, $4 or some other
> predefined variable.
>
> Some code to illustrate my problem:
>
> $regexp = "(\d)(\w)(\d)";
> $numb = 3; # Means the result I'm looking for is in $3
> # I don't know this number, it's submitted
> by user
> # and may differ
>
> if ($data =~ /$regexp/) {
>
> print $numb; # does not work, prints "3"


What you are trying to do is use something called a symbolic ref:

print $$numb; # works - print value of $3

But you have to be careful using symrefs...

{
# Untaint and check $numb - don't clobber $1 etc
die 'Not a number' unless do { ($numb) = $numb =~ /(^\d+$)/ };
no strict 'refs';
print $$numb;
}

That said I wouldn't use one myself because I never use $1 etc (other
than in the RHS of s/// or in while(//g).

if (my @captures = $data =~ /$regexp/) {
print $captures[$numb-1];
}


Gunnar Hjalmarsson 08-26-2004 04:59 PM

Re: using the result of a variable regular expression
 
leifwessman@hotmail.com wrote:
> I need to extract a certain value from a text. But the result isn't
> always in the variable $1 - it might be in $2, $3, $4 or some other
> predefined variable.
>
> Some code to illustrate my problem:


Your problem starts before that code: You have not enabled strictures
and warnings!

use strict;
use warnings;

> $regexp = "(\d)(\w)(\d)";


There is your second problem: $regex get the value '(d)(w)(d)', which
is not what you want.

my $regexp = '(\d)(\w)(\d)';
-----------------^------------^

1) Please copy and paste code that you post, do not retype it!

2) Warnings would have told you that something was wrong.

> $numb = 3; # Means the result I'm looking for is in $3
> # I don't know this number, it's submitted by user
> # and may differ
>
> if ($data =~ /$regexp/) {
>
> print $numb; # does not work, prints "3"
>
> # alternative solution that works
> # but it's UGLY
> if ($numb == 1) {
> print $1;
> } elsif ($numb == 2) {
> print $2;
> } elsif ($numb == 3) {
> print $3;
> }
>
> # is there another way?
> }


You can do:

if ( my @capt = $data =~ /$regexp/ ) {
print $capt[$numb-1];
}

--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl

Anno Siegel 08-26-2004 05:41 PM

Re: using the result of a variable regular expression
 
Gunnar Hjalmarsson <noreply@gunnar.cc> wrote in comp.lang.perl.misc:
> leifwessman@hotmail.com wrote:
> > I need to extract a certain value from a text. But the result isn't
> > always in the variable $1 - it might be in $2, $3, $4 or some other
> > predefined variable.
> >
> > Some code to illustrate my problem:

>
> Your problem starts before that code: You have not enabled strictures
> and warnings!
>
> use strict;
> use warnings;
>
> > $regexp = "(\d)(\w)(\d)";

>
> There is your second problem: $regex get the value '(d)(w)(d)', which
> is not what you want.
>
> my $regexp = '(\d)(\w)(\d)';
> -----------------^------------^
>
> 1) Please copy and paste code that you post, do not retype it!
>
> 2) Warnings would have told you that something was wrong.
>
> > $numb = 3; # Means the result I'm looking for is in $3
> > # I don't know this number, it's submitted by user
> > # and may differ
> >
> > if ($data =~ /$regexp/) {
> >
> > print $numb; # does not work, prints "3"
> >
> > # alternative solution that works
> > # but it's UGLY
> > if ($numb == 1) {
> > print $1;
> > } elsif ($numb == 2) {
> > print $2;
> > } elsif ($numb == 3) {
> > print $3;
> > }
> >
> > # is there another way?
> > }

>
> You can do:
>
> if ( my @capt = $data =~ /$regexp/ ) {
> print $capt[$numb-1];
> }


Or, without an auxiliary variable:

defined and print for ( $data =~ /$regex/ )[ $numb - 1];

Anno

Anno Siegel 08-26-2004 05:57 PM

Re: using the result of a variable regular expression
 
Gunnar Hjalmarsson <noreply@gunnar.cc> wrote in comp.lang.perl.misc:
> leifwessman@hotmail.com wrote:


> > I need to extract a certain value from a text. But the result isn't
> > always in the variable $1 - it might be in $2, $3, $4 or some other
> > predefined variable.


> You can do:
>
> if ( my @capt = $data =~ /$regexp/ ) {
> print $capt[$numb-1];
> }


Or, without an auxiliary variable:

defined and print for ( $data =~ /$regex/ )[ $numb - 1];

Anno

Tore Aursand 08-26-2004 06:40 PM

Re: using the result of a variable regular expression
 
On Thu, 26 Aug 2004 09:19:34 -0700, leifwessman wrote:
> Some code to illustrate my problem:
> [...]


Your code won't run. Please copy-and-paste working code, instead of
retyping it.

You should also add these:

use strict;
use warnings;

> $regexp = "(\d)(\w)(\d)";
> $numb = 3; # Means the result I'm looking for is in $3
> # I don't know this number, it's submitted
> by user
> # and may differ
>
> if ($data =~ /$regexp/) {
>
> print $numb; # does not work, prints "3"
>
> # alternative solution that works
> # but it's UGLY
> if ($numb == 1) {
> print $1;
> } elsif ($numb == 2) {
> print $2;
> } elsif ($numb == 3) {
> print $3;
> }
>
> # is there another way?
> }


You can match into an array;

if ( my @match = $data =~ /$regexp/ ) {
print @match[$numb-1];
}


--
Tore Aursand <tore@aursand.no>
"Computer science education cannot make anybody an expert programmer
any more than studying brushes and pigment can make somebody an expert
painter." (Eric Raymond)

John W. Krahn 08-26-2004 07:13 PM

Re: using the result of a variable regular expression
 
leifwessman@hotmail.com wrote:
>
> I need to extract a certain value from a text. But the result isn't
> always in the variable $1 - it might be in $2, $3, $4 or some other
> predefined variable.
>
> Some code to illustrate my problem:
>
> $regexp = "(\d)(\w)(\d)";
> $numb = 3; # Means the result I'm looking for is in $3
> # I don't know this number, it's submitted
> by user
> # and may differ
>
> if ($data =~ /$regexp/) {
>
> print $numb; # does not work, prints "3"
>
> # alternative solution that works
> # but it's UGLY
> if ($numb == 1) {
> print $1;
> } elsif ($numb == 2) {
> print $2;
> } elsif ($numb == 3) {
> print $3;
> }
>
> # is there another way?
> }


You are extracting single characters. How about substr()?

print substr( $data, $numb - 1, 1 )


Why not define your regexp based on the submitted value?

my @fields = ( '\d', '\w', '\d' );
$fields[ $numb - 1 ] = '(' . $fields[ $numb - 1 ] . ')';
my $regexp = join '', @fields;
if ( $data =~ /$regexp/ ) {
print $1;
}


Or you could use the @+ and @- arrays:

my $regexp = '(\d)(\w)(\d)';
if ( $data =~ /$regexp/ ) {
print substr( $data, $-[ $numb ], $+[ $numb ] - $-[ $numb ] );
}



John
--
use Perl;
program
fulfillment

Brian McCauley 08-27-2004 12:05 PM

Re: using the result of a variable regular expression
 
Anno Siegel wrote:

> Gunnar Hjalmarsson <noreply@gunnar.cc> wrote in comp.lang.perl.misc:
>>You can do:
>>
>> if ( my @capt = $data =~ /$regexp/ ) {
>> print $capt[$numb-1];
>> }

>
>
> Or, without an auxiliary variable:
>
> defined and print for ( $data =~ /$regex/ )[ $numb - 1];


In this particular case it is probably safe to assume that we want to
treat the case where the ${numb}th capture didn't capture to be
equivalent to the case where /$regex/ didn't match.

However it is important to be aware that you are making such an assumption.


Anno Siegel 08-27-2004 12:44 PM

Re: using the result of a variable regular expression
 
Brian McCauley <nobull@mail.com> wrote in comp.lang.perl.misc:
> Anno Siegel wrote:
>
> > Gunnar Hjalmarsson <noreply@gunnar.cc> wrote in comp.lang.perl.misc:
> >>You can do:
> >>
> >> if ( my @capt = $data =~ /$regexp/ ) {
> >> print $capt[$numb-1];
> >> }

> >
> >
> > Or, without an auxiliary variable:
> >
> > defined and print for ( $data =~ /$regex/ )[ $numb - 1];

>
> In this particular case it is probably safe to assume that we want to
> treat the case where the ${numb}th capture didn't capture to be
> equivalent to the case where /$regex/ didn't match.
>
> However it is important to be aware that you are making such an assumption.


You are right. I thought about explaining how it is okay (under this
assumption) to use the regex without explicitly checking if it matched,
but decided to let it slip. Thanks for pointing it out.

Anno

Sara 08-27-2004 02:44 PM

Re: using the result of a variable regular expression
 
leifwessman@hotmail.com wrote in message news:<cgl2im$tru@odak26.prod.google.com>...
> Hi!
>
> I need to extract a certain value from a text. But the result isn't
> always in the variable $1 - it might be in $2, $3, $4 or some other
> predefined variable.
>
> Some code to illustrate my problem:
>
> $regexp = "(\d)(\w)(\d)";
> $numb = 3; # Means the result I'm looking for is in $3
> # I don't know this number, it's submitted
> by user
> # and may differ
>
> if ($data =~ /$regexp/) {
>
> print $numb; # does not work, prints "3"
>
> # alternative solution that works
> # but it's UGLY
> if ($numb == 1) {
> print $1;
> } elsif ($numb == 2) {
> print $2;
> } elsif ($numb == 3) {
> print $3;
> }
>
> # is there another way?
> }
>
> Thanks for any input!
>
> Leif


Hi there Leif:

Interesting question. As pointed out, $$numb will work nicely for you.
The odd thing being that this LOOKS like a scalar dereference, which
it really isn't since 2 isn't the memory location of the value. Seems
like there is an ambiguity in there somewhere but I can't pinpoint it.

Thanks for posting.

G


All times are GMT. The time now is 08:07 AM.

Powered by vBulletin®. Copyright ©2000 - 2013, vBulletin Solutions, Inc.
SEO by vBSEO ©2010, Crawlability, Inc.


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