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

Given:

while(<>) { s/(\d),(?=\d)/$1|$2/g; print; }
This triggers a warning of Use of uninitialized value in concatenation (.) or string whenever the regex matches.

Which I don't comprehend:
$_ is defined
$1 and $2 are both defined when the match occurs.
So why does the warning trigger?


Be Appropriate && Follow Your Curiosity

Replies are listed 'Best First'.
Re: regex match triggers "Use of unititialized value ..." warning
by BrowserUk (Patriarch) on Feb 22, 2011 at 02:30 UTC
    $1 and $2 are both defined when the match occurs.

    That can't be as there is only one set of capturing parens. The second set of parens are a non-capturing lookahead.

    This would probably do what you are trying to achieve:

    s/(?<=\d),(?=\d)/|/g;

    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority".
    In the absence of evidence, opinion is indistinguishable from prejudice.

      Hey future readers,
      If your Perl history has not involved look-ahead and look-behind regexes, this Q&A, especially BrowserUk's A, make for a nice learning opportunity.

      Well, nice if you consider my mis-use something that can be learned from.


      Be Appropriate && Follow Your Curiosity
Re: regex match triggers "Use of unititialized value ..." warning
by hsinclai (Deacon) on Feb 22, 2011 at 02:34 UTC
    There is no $2, actually.
    So to clarify, sorry, the creation of a string: $1, then character |, then $2, fails.


    update: typo clarifications
Re: regex match triggers "Use of unititialized value ..." warning
by toolic (Bishop) on Feb 22, 2011 at 02:32 UTC
    Show us a few lines of your input which trigger the warning message, preferably as a self-contained code sample using __DATA__:
    while(<DATA>) { s/(\d),(?=\d)/$1|$2/g; print; } __DATA__

      I didn't include it, as I thought it was trivial..

      #!/usr/bin/perl use strict; use warnings; my $cnt; while(<DATA>) { $cnt++; print "$cnt line\n"; s/(\d),(?=\d)/$1|$2/g; print; } __DATA__ work with 19,43 or so 14,99 we have, at most, 14,23 to do though some say it is 18,44 Without digits, all the , will remain. With digits 9, Ah ha! or With,3 no change for a 2nd line But again 3,4,5,6 all have bars.


      Be Appropriate && Follow Your Curiosity

      $2 doesn't exist. So that's cleared up now. Thank you. Removing $2 from the code removes the warnings, gives the expected output and all is well.


      Be Appropriate && Follow Your Curiosity