Zyzyx
Zyzyx

Reputation: 534

Regex $1 into variable interferes with another variable

I have been struggling with a section of my code for a while now and can't figure it out. Seems to have something to do with how $1 is handled but I cannot find anything relevant.

The regex finds the 16640021 and assigns it to a position in the arrays.

my @one;
my @two;
my $articleregex = qr/\s*\d*\/\s*\d*\|\s*(.*?)\|/p; # $1 = article number
my $row = "   7/  1|        16640021|Taats 3 IP10                       |14-03-03|        |    |        1,0000|st |   | 01|    | N|  0|";

    if ($row =~ /$articleregex/g) {
        $one[0] = $1; 
    }
    if ($row =~ /$articleregex/g) { 
        $two[0] = $1;
    }
print $one[0];
print $two[0];

Which outputs

Use of uninitialized value in print at perltest3.pl line 13.
16640021

It appears that the designation of $one[0] somehow interferes with that of $two[0]. This seems strange to me as the two variables and their designations should not be interacting in any way

Upvotes: 1

Views: 69

Answers (1)

ikegami
ikegami

Reputation: 386706

It's because you used if (//g) instead of if (//).

  • //g in scalar context sets pos($_)[1] to where the match left off, or unsets pos($_)[1] if the match was unsuccessful[2].
  • //g in scalar context starts matching at position pos($_)[1].

For example,

$_ = "ab";
say /(.)/g ? $1 : "no match";  # a
say /(.)/g ? $1 : "no match";  # b
say /(.)/g ? $1 : "no match";  # no match
say /(.)/g ? $1 : "no match";  # a

This allows the following to iterate through the matches:

while (/(.)/g) {
   say $1;
}

Don't use if (//g)[3]!


  1. $_ is being used to represent the variable being matched against.
  2. Unless /c is also used.
  3. Unless you're unrolling a while (//g), or unless you're using if (//gc) to tokenize.

Upvotes: 6

Related Questions