in reply to Use of uninitialized value $1

Well, only if you 'use warnings', the compiler tells you that $1 has never been defined, and thus, can not be printed. If you want to capture "lib" in $1, then you need to use parenthesis in your regular expression. Like so:

use v5.10; use warnings; use strict; my $var; $var = "path_to_my_lib"; $var =~ m/(lib)/; say $1;

Which prints the captured "lib" (and gives no warnings).

$1, $2.. etc are weird variables. You can not assign them a value, and they disappear when they go out of scope, or a new regexp is encountered. You can solve it in a few ways, for example, test it before using it:

if($1){ say $1; }

or test the regular expression to match:

if( $var =~ m/(foo)/ ){ say $1; }else{ say "no match found"; }

Replies are listed 'Best First'.
Re^2: Use of uninitialized value $1
by AnomalousMonk (Archbishop) on Aug 25, 2016 at 12:29 UTC
    $1, $2.. etc are weird variables. ... they disappear when ... a new regexp is encountered. [Emphasis Added]

    Even more weird! These variables keep their value until a new regex is successfully matched or dynamic scope is exited.

    c:\@Work\Perl\monks>perl -wMstrict -MData::Dump -le "my $str = 'foo--bar'; dd $1, $2; ;; $str =~ m{ (foo) .* (bar) }xms; print qq{A: \$1 '$1' \$2 '$2'}; ;; $str =~ m{ (x) .* (y) }xms; print qq{B: \$1 '$1' \$2 '$2'}; " (undef, undef) A: $1 'foo' $2 'bar' B: $1 'foo' $2 'bar'


    Give a man a fish:  <%-{-{-{-<

      "These variables keep their value until a new regex is successfully matched or dynamic scope is exited."

      I'm not sure that is true. I remember a node that fairly recently talked about this, but I couldn't find it, only What's happening to my $1?.

      What I remember is that a failed match could in some circumstances modify $1. So $1 is only reliable if the match succeeds (can't rely upon it being what it was after the previous regex after a failed match). I also remember that this behavior is Perl version specific.

      I haven't run across this in my code as I do whatever I'm going to do with $1 right after the regex and have never written code that decides whether $1 changed or not. I only use $1 if the match succeeded.

      Yes, this is a nit, but Perl Monks is good about resolving these nits and details.

        Yes, this is a nit ...

        Regular expressions, love them though I do, consist in a vast collection of nits IMHO.

        I'm not sure that [these variables keep their value] is true. I remember a node that fairly recently talked about this, but I couldn't find it ... What I remember is that a failed match could in some circumstances modify $1.

        Now that you mention it, I seem to remember something along those lines myself. Unfortunately, my Super Search-fu is no better than yours, and I could come up with no pertinent node. Have to keep searching, searching... (Maybe it had to do with the match portion of  s/// having the same effects on regex variables as  m// does?)

Re^2: Use of uninitialized value $1
by Pazitiff (Novice) on Aug 25, 2016 at 12:27 UTC
    Thanks! But what if i want capture the left word ("path_to_my_") of "lib"? In general, I need a regular expression to get what is left of the "lib". How this can be done using $1, $2, $3 ? Thanks. Sorry, but i have no experience in Perl and RX.

      The Devil is in the Details! Exactly what are you matching against, and exactly what do you want to match?

      c:\@Work\Perl\monks>perl -wMstrict -le "my $var = '%&!~ path_to_a_lib_of_my_lib'; ;; $var =~ m{ (.*) lib }xms; print qq{A: '$1'}; ;; $var =~ m{ (.*?) lib }xms; print qq{B: '$1'}; ;; $var =~ m{ (\w*?) lib }xms; print qq{C: '$1'}; " A: '%&!~ path_to_a_lib_of_my_' B: '%&!~ path_to_a_' C: 'path_to_a_'

      Update: Please see perlre, perlretut, and perlrequick.

      Further Update: If the string consists entirely in something like 'path_to_a_lib_of_my_lib', see also the start- and end-of-string "anchors"  \A \z \Z (particularly  \A \z in this case) for further narrowing what you want to capture.


      Give a man a fish:  <%-{-{-{-<

      my $v = '/path/to/module.pm'; $v =~ m{^(.*)/(.*)$}; say "($1) ($2)";

      prints out:

      (/path/to) (module.pm)

      Thus, if you want your module name hardcoded:

      my $modulepath; if($v =~ m{^(.*)module.pm$}){ $modulepath = $1; }

      additional note: usually you write m// with slashes, but I write it with m{} brackets. This is also valid and allows you to use / inside the regexp, without having to escape it with a backslash.