How to use special variable in regex?

P

Peng Yu

Hi,

I want to use some variable in regex. But the below code does not work
as I expected. Can somebody let me know what I am wrong?

Thanks,
Peng

#!/usr/bin/perl

use warnings;
use strict;

my @array = ('a' , 'b');
my @strings = ('aa', 'ab', 'ba', 'bb', 'cc', 'cd');

foreach (@array) {
print "$_\n";
my @subset = grep(/^$_.+$/, @strings);
# The above line does not work as I want
# I want search for all the stings in @strings
# that are started with a letter in @array.
foreach (@subset) {
print "$_\n";
}
}

print "here\n";

my @subset = grep(/^a.+$/, @strings);
foreach (@subset) {
print "$_\n";
}
 
T

Todd

For the 2 sentences below:

print "$_\n"; # -- #1
my @subset = grep(/^$_.+$/, @strings); # -- #2

the $_ inside grep is an alias to the current processing element in
@string. So @subset will always be empty.

Check 2 examples below and check the difference.

#! /bin/perl -lw

$_ = "a";
print scalar grep (/^$_.+/, (a1, a2, a3));

__END__

0


#! /bin/perl -lw

$v = "a";
print scalar grep (/^$v.+/, (a1, a2, a3));

__END__

3



-Todd
 
J

John W. Krahn

Peng said:
I want to use some variable in regex. But the below code does not work
as I expected. Can somebody let me know what I am wrong?

#!/usr/bin/perl

use warnings;
use strict;

my @array = ('a' , 'b');
my @strings = ('aa', 'ab', 'ba', 'bb', 'cc', 'cd');

foreach (@array) {
print "$_\n";
my @subset = grep(/^$_.+$/, @strings);

That is short for:

my @subset = grep( $_ =~ /^$_.+$/, @strings );

So you are trying to match the current element of @strings against the
current element of @strings plus one character. And since the current
element of @strings cannot have more characters than the current element
of @strings it will never match.

What you want is:

foreach my $element ( @array ) {
print "$element\n";
my @subset = grep /^$element.+$/, @strings;



John
 
B

Bart Lateur

Peng said:
I want to use some variable in regex. But the below code does not work
as I expected. Can somebody let me know what I am wrong?

my @array = ('a' , 'b');
my @strings = ('aa', 'ab', 'ba', 'bb', 'cc', 'cd');

foreach (@array) {
print "$_\n";
my @subset = grep(/^$_.+$/, @strings);

You're using $_ for two purposes, as your ordinary loop variable, and as
the variable in grep. You're hoping to use a different variable, but of
course, it'll use the same value twice: as the variable for grep.

The fix is to use a different loop variable:

foreach my $r (@array) {
print "$r\n";
my @subset = grep(/^$r.+$/, @strings);
...

Although you could use a copy of the loop variable:

foreach (@array) {
print "$_\n";
my $r = $_;
my @subset = grep(/^$r.+$/, @strings);
 
D

Dr.Ruud

Peng Yu schreef:
my @subset = grep(/^$_.+$/, @strings);

Since you are not capturing, /^$_./ should do.

Or use length()>1 and index()==0.
Or "substr($string, 0, 1) eq $_" in stead of index()==0.
 
P

Peter J. Holzer

That is short for:

my @subset = grep( $_ =~ /^$_.+$/, @strings );

So you are trying to match the current element of @strings against the
current element of @strings plus one character. And since the current
element of @strings cannot have more characters than the current element
of @strings it will never match.


my @strings = ('a*');

my @subset = grep( $_ =~ /^$_.+$/, @strings );
foreach (@subset) {
print "$_\n";
}

SCNR,
hp
 
S

sln

my @strings = ('a*');

my @subset = grep( $_ =~ /^$_.+$/, @strings );
foreach (@subset) {
print "$_\n";
}

SCNR,
hp

Yes, clever.
---------------------------
use strict;
use warnings;

my $elem0 = 'a*';
my @strings = ($elem0);

my @subset = grep( s/^($_)(.+)$/$1-$2/, @strings );
foreach (@subset) {
print "$_\n";
}
my $evalstr =
"
print \"\\\$elem0 = \$elem0\\n\";
if (\$elem0 =~ s/^($elem0)(.+)\$/\$1-\$2/)
{
print \"\\\$elem0 = \$elem0, \\\$1 = \$1, \\\$2 = \$2\\n\";
}";

print "\n$evalstr\n";
eval $evalstr;

__END__

a-*

print "\$elem0 = $elem0\n";
if ($elem0 =~ s/^(a*)(.+)$/$1-$2/)
{
print "\$elem0 = $elem0, \$1 = $1, \$2 = $2\n";
}
$elem0 = a*
$elem0 = a-*, $1 = a, $2 = *
 

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,961
Messages
2,570,130
Members
46,689
Latest member
liammiller

Latest Threads

Top