Home > Archive > PERL Beginners > December 2007 > help in variable pattern matching
You are viewing an archived Text-only version of the thread.
To view this thread in it's original format and/or if you want to reply to
this thread please [click here]
| Author |
help in variable pattern matching
|
|
| Jin Zhisong 2007-12-19, 10:03 pm |
| HI, I'm looking for some advice of how to do this?
I need to match some "variable" pattenrs so
I define a $match variable and use it in the patterr below.
However it didn't match anything for the sample data.
If I change the match critia to hardcode
next unless /\s+BCV\s+N/Grp/; it works
if I
next unless /\s+BCV\s+N\/Grp/; it didn't work
so my question are
1. what is the proper way to use \ within regex?
2. can I use $match within regex , sun as / $match ../, should I quote
' or "" for $match ?
3. can I use ${match} to make it more readiable?
Thanks.
Jason
===== code segment ===
my $sid = $ARGV[0];
my $type = $ARGV[1];
my @devices = find_avaiable_devices ();
sub find_available_devices {
my @finds = ();
my $match = ( $type eq 'bcv' ) ? 'BCV' : 'RAID-5' ;
open (AVAIL, "$symdev list -sid $sid -noport -$type |" ) or die
"cannot open $!\n";
while ( <AVAIL> ) {
next unless /Not Visible.*\d\d[A-D]:[A-D][0-3]\s+${match}\s+N\/Grp/;
my ($device , $type, $size) = ( split )[0,5,8];
push @finds , $device if defined $device ;
}
return @finds;
__END__
# Sample output from ""$symdev list -sid $sid -noport -$type" below
__DATA__
05F3 Not Visible ???:? 16A:CF RAID-5 N/Grp'd RW
9492
05F4 Not Visible ???:? 01A:DF RAID-5 N/Grp'd RW
9492
05F5 Not Visible ???:? 16A:D10 RAID-5 N/Grp'd RW
9492
05F6 Not Visible ???:? 01A:C10 RAID-5 N/Grp'd RW
9492
05F7 Not Visible ???:? 16A:CF RAID-5 N/Grp'd RW
9492
05FA Not Visible ???:? 16A:D0 BCV N/Asst'd RW
9492
05FB Not Visible ???:? 16D:C0 BCV N/Asst'd RW
9492
05FC Not Visible ???:? 01A:C0 BCV N/Asst'd RW
9492
05FD Not Visible ???:? 16B:C0 BCV N/Asst'd RW
9492
| |
| Roberto Etcheverry 2007-12-19, 10:03 pm |
| Jin Zhisong wrote:
> HI, I'm looking for some advice of how to do this?
>
>
>
> I need to match some "variable" pattenrs so
>
>
>
> I define a $match variable and use it in the patterr below.
>
> However it didn't match anything for the sample data.
>
>
>
> If I change the match critia to hardcode
>
> next unless /\s+BCV\s+N/Grp/; it works
>
This line gives me a syntax error (Bareword found where operator expected)
> if I
>
> next unless /\s+BCV\s+N\/Grp/; it didn't work
>
This regular expression matches one or more spaces, "BCV", one or more
spaces and "N/Grp" (i.e., " BCV N/Grp")
>
>
> so my question are
>
> 1. what is the proper way to use \ within regex?
>
You use '' when you want to match literally some character that
otheways would be interpreted as an operator ('+', '*', etc.) or end of
regex (like '/' in the example above). Just to be sure, escape with ''
any non alphanumeric you want to match literally.
> 2. can I use $match within regex , sun as / $match ../, should I quote
> ' or "" for $match ?
>
You can use $match alone or ${match} (safer).
> 3. can I use ${match} to make it more readiable?
>
Yes, it's better.
>
>
> Thanks.
>
> Jason
>
>
>
> ===== code segment ===
>
> my $sid = $ARGV[0];
>
> my $type = $ARGV[1];
>
>
>
> my @devices = find_avaiable_devices ();
>
>
>
> sub find_available_devices {
>
> my @finds = ();
>
> my $match = ( $type eq 'bcv' ) ? 'BCV' : 'RAID-5' ;
>
>
>
> open (AVAIL, "$symdev list -sid $sid -noport -$type |" ) or die
> "cannot open $!\n";
>
>
>
> while ( <AVAIL> ) {
>
>
>
> next unless /Not Visible.*\d\d[A-D]:[A-D][0-3]\s+${match}\s+N\/Grp/;
>
>
>
> my ($device , $type, $size) = ( split )[0,5,8];
>
> push @finds , $device if defined $device ;
>
> }
>
> return @finds;
>
>
>
>
>
> __END__
>
>
>
> # Sample output from ""$symdev list -sid $sid -noport -$type" below
>
> __DATA__
>
> 05F3 Not Visible ???:? 16A:CF RAID-5 N/Grp'd RW
> 9492
>
> 05F4 Not Visible ???:? 01A:DF RAID-5 N/Grp'd RW
> 9492
>
> 05F5 Not Visible ???:? 16A:D10 RAID-5 N/Grp'd RW
> 9492
>
> 05F6 Not Visible ???:? 01A:C10 RAID-5 N/Grp'd RW
> 9492
>
> 05F7 Not Visible ???:? 16A:CF RAID-5 N/Grp'd RW
> 9492
>
>
>
> 05FA Not Visible ???:? 16A:D0 BCV N/Asst'd RW
> 9492
>
> 05FB Not Visible ???:? 16D:C0 BCV N/Asst'd RW
> 9492
>
> 05FC Not Visible ???:? 01A:C0 BCV N/Asst'd RW
> 9492
>
> 05FD Not Visible ???:? 16B:C0 BCV N/Asst'd RW
> 9492
>
>
>
>
>
| |
| Tom Phoenix 2007-12-19, 10:03 pm |
| On 12/19/07, Jin Zhisong <Zhisong.Jin@irs.gov> wrote:
> next unless /\s+BCV\s+N/Grp/; it works
Oh, I hope it doesn't work. The number of forward slashes is all wrong.
> next unless /\s+BCV\s+N\/Grp/; it didn't work
But this one might actually parse. If it doesn't match when it's
supposed to, and fail when it's supposed to, that's another problem.
(Does it matter that no line in your sample data has both "BCV" and
"N/Grp"?)
> 1. what is the proper way to use \ within regex?
If you need to use the quoting character ("/" in your pattern above)
as an actual literal character in the pattern, you need to backslash
it, as you did in your second pattern above. That tells Perl that this
isn't the end-of-pattern delimiter, this is a literal character. But
because patterns like this:
/^\/usr\/bin\//
.... are hard to read and write, Perl lets you choose a different
punctuation mark than the forward slash as a quoting character. In
exchange, you have to warn Perl that you want a pattern match by
putting the letter m in front of your pattern. That ugly pattern above
might thus become:
m#^/usr/bin/#
.... if you choose the #-sign as a delimiter.
On the other hand, the backslash character is always special in Perl.
If you mean a literal backslash character within a string or a
pattern, you always need to use two of them.
> 2. can I use $match within regex , sun as / $match ../, should I quote
> ' or "" for $match ?
I'm not completely sure what you're asking, but I think you want to
know about building a pattern at run-time by interpolating a variable
into a pattern. Yes, you can interpolate a variable such as $match
into a pattern; you'll generally want the qr// operator to quote the
pieces you use to make $match.
http://perldoc.perl.org/perlop.html...-Like-Operators
> 3. can I use ${match} to make it more readiable?
If you think it's more readable, then you should be able to use it.
But maybe you really want to add the /x flag to your pattern, and
write it so that it's _really_ readable.
While you're still developing your program and trying to get your
pattern to match, you don't need to keep running your external
program. Run it once, save the output to a file, then have your
program read that file. That makes it easier to step through your code
with the debugger, and it's better for testing because the data
doesn't change from one run to the next.
In fact, it would be arguably better to design your program so that it
can work on either a given data file or the external program's output.
That would allow you to easily make a test program that checks that
your program behaves correctly when given known test data, so you
could have more confidence in its behavior when its data comes from
the external program.
Hope this helps!
--Tom Phoenix
Stonehenge Perl Training
| |
| Dr.Ruud 2007-12-19, 10:03 pm |
| "Jin Zhisong" schreef:
> I define a $match variable and use it in the patterr below.
> However it didn't match anything for the sample data.
perldoc -f qr
--
Affijn, Ruud
"Gewoon is een tijger."
| |
| Tom Phoenix 2007-12-19, 10:03 pm |
| On 12/19/07, Jin Zhisong <Zhisong.Jin@irs.gov> wrote:
> The following code didn't work.
> my $pattern = ( $type eq 'bcv' ) ? "${match}\s+N\/Asst" :
> "${match}\s+N\/Grp" ;
Did it not work because it did not use qr//? That's at least part of
the problem. It may help you during development if you output the
value of $pattern, so you can see whether it's getting built as you
expect.
Cheers!
--Tom Phoenix
Stonehenge Perl Training
| |
| Jin Zhisong 2007-12-19, 10:03 pm |
|
Thanks every one that helps. I find my problem. Now how=20
can I have a $pattern that contain some special characters
to pass it into regex? =20
I want to extract the line that contains either=20
RAID-5 N/Grp'd =20
Or=20
BCV N/Asst'd =20
The following code didn't work. =20
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=3D=
=3D=3D=3D=3D=3D=3D
My $type =3D $ARGV[1]
my $match =3D ( $type eq 'bcv' ) ? 'BCV' : 'RAID-5' ;
my $pattern =3D ( $type eq 'bcv' ) ? "${match}\s+N\/Asst" :
"${match}\s+N\/Grp" ;
=20
while ( <DATA> ) {
next unless /$pattern/;
print $_ ;=20
}=20
__DATA__
05F3 Not Visible ???:? 16A:CF RAID-5 N/Grp'd RW 9492
05F5 Not Visible ???:? 16A:D10 RAID-5 N/Grp'd RW 9492
0031 Not Visible ???:? 01C:C0 2-Way Mir N/Grp'd RW 9492
05FA Not Visible ???:? 16A:D0 BCV N/Asst'd RW
9492
05FC Not Visible ???:? 01A:C0 BCV N/Asst'd RW
9492
| |
| Gunnar Hjalmarsson 2007-12-19, 10:03 pm |
| Jin Zhisong wrote:
> The following code didn't work.
> ========================================
================
>
> My $type = $ARGV[1]
>
> my $match = ( $type eq 'bcv' ) ? 'BCV' : 'RAID-5' ;
> my $pattern = ( $type eq 'bcv' ) ? "${match}\s+N\/Asst" :
> "${match}\s+N\/Grp" ;
>
> while ( <DATA> ) {
> next unless /$pattern/;
> print $_ ;
>
> }
In addition to Tom's comment, you'd better add
use strict;
use warnings;
at the beginning of your script. That makes Perl give you an indication
of what the problem is.
--
Gunnar Hjalmarsson
Email: http://www.gunnar.cc/cgi-bin/contact.pl
|
|
|
|
|