Beefy Boxes and Bandwidth Generously Provided by pair Networks
"be consistent"
 
PerlMonks  

regex matching with $1

by c (Hermit)
on Oct 26, 2001 at 01:26 UTC ( [id://121543]=perlquestion: print w/replies, xml ) Need Help??

c has asked for the wisdom of the Perl Monks concerning the following question:

i have the following code:

#!/usr/bin/perl -w use strict; my $line = q|$mypic[0] = "one"|; $line =~ s/^\$mypic\[0\] = \"(\w{3})\"\;$/$1/g; print "$line\n";

and i am not sure why the $1 isnt turning out to be one. instead the print statement ends up spitting out the whole line, and i dont understand why.

humbly -c

Replies are listed 'Best First'.
Re: regex matching with $1
by dvergin (Monsignor) on Oct 26, 2001 at 01:36 UTC
    Your substitution regex is failing because you are trying to match the semicolon at the end of the previous line. But that is not part of the quoted value being entered into $line.

    You also have a bit more escaping than necessary. Try this: $line =~ s/^\$mypic\[0] = "(\w{3})"$/$1/g;

    FWIW #1: This is a good example of the problem with using a regex in this way. You may have been thinking that your regex was doing something magically strange to spit back the whole line. In fact it simply failed. So when you do this for the purpose of retreiving a value you almost always want to do something like:

    my $newval; if ($line =~ /^\$mypic\[0] = "(\w{3})"$/) { $newval = $1; } else { # handle failure to get essential value }
    If that looks like too much code and you remember that a regex with parentheses returns those saved values when it is in a list context, you can do this:
    my $newval; unless ( ($newval) = $line =~ /(\w{3})"$/ ) { # handle failure to get essential value }
    For comment on this shorter regex, read on...

    FWIW #2: Your question may be more of an exercise than a practical application. But to the extent that this is for some real and specific need, I tend to keep my regexen to the minimum to do the job and try not to get into the trap of matching the entire data string if that is not needed for filtering purposes.

    In this case something along the lines of: /(\w{3})"$/ seems to do what you need (within the bounds of this limited example). There are always anomalies that crop up in the data and the more I try to match everything, the more likely it is that the regex could fail for unforeseen reasons.

    The notable exception to this habit is when the task is security or access related. Then I get very picky about what I let through.

    This may not apply to your present purpose, but it is something that struck me immediately about your longer regex.

    HTH, David

Re: regex matching with $1
by jynx (Priest) on Oct 26, 2001 at 01:33 UTC

    It seems,

    Your regex in the first part of the substitution isn't matching $line exactly. Because of this the substitution isn't happening (and therefore the unmodified version prints). Namely, you don't have a semi-colon in $line. If you take out the semi-colon and the back-slash from the substitution (or add a semi-colon to $line) it should work properly.

    Hope This Helps,
    jynx

Re: regex matching with $1
by {NULE} (Hermit) on Oct 26, 2001 at 01:39 UTC
    Hi,

    Because there isn't a semicolon in your $line:
    $line =~ s/^\$mypic\[0\] = \"(\w{3})\"$/$1/g;
    works.

    That's one reason why I often use if() around my regexp stuff.
    {NULE}

    Update: Wow, two other people replied before I could type mine up. Aren't we a speedy crew? :)
    --
    http://www.nule.org

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://121543]
Approved by root
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others drinking their drinks and smoking their pipes about the Monastery: (3)
As of 2024-04-26 00:33 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found