in reply to Re^2: Repeated Pattern Matching Fails
in thread Repeated Pattern Matching Fails

You are using the /g option on a pattern in boolean context which means that the first time it will match and the second time it will continue searching where the first match ended and will therefore not find another match and will return "false".

Replies are listed 'Best First'.
Re^4: Repeated Pattern Matching Fails
by ikegami (Patriarch) on Jan 28, 2009 at 15:35 UTC

    Nit: "Boolean context" is not relevant. Scalar vs list is what makes the difference.

    print's operands are evaluated in both list context and string context. Is there an operator that has operands in both list context and boolean context? It would be possible to write such a sub.

Re^4: Repeated Pattern Matching Fails
by Marshall (Canon) on Jan 28, 2009 at 14:01 UTC
    Answer is correct, but some fine points.
    I didn't realize that you had previously matched same string with a /g(global match)...as a demo to show what happens:
    use warnings; use strict; my $_sensor_type = "I2600A8600C9800"; if($_sensor_type =~ /[a-z]+([0-9]+)/ig) { print "$1 OK\n"; #prints Ok } while ($_sensor_type =~ /[a-z]+([0-9]+)/ig) { print "$1 OK with global loop\n"; } __END__ prints: 2600 OK 8600 OK with global loop 9800 OK with global loop So happened to the first "I2600", answer is the /g in first match! Don't use /g (global unless you mean to use this in a list context) my $_sensor_type = "I2600A8600C9800"; if($_sensor_type =~ /[a-z]+([0-9]+)/i) { print "$1 OK\n"; #prints Ok } while ($_sensor_type =~ /[a-z]+([0-9]+)/ig) { print "$1 OK with global loop\n"; } __END__ now you get: 2600 OK 2600 OK with global loop 8600 OK with global loop 9800 OK with global loop
      Yet some more code about this... the /g operation generates a list, below I assign all regex matches to a list called @types.
      use warnings; use strict; my $_sensor_type = 'I2600*&^_A8699()^%#@C9800&*%A96'; my @types = $_sensor_type =~ /[a-z]+([0-9]+)/ig; #parens aren't needed here but to make list clear, #could have been: #my @types = ($_sensor_type =~ /[a-z]+([0-9]+)/ig); print join("\n",@types),"\n"; __END__ ## prints ### 2600 8699 9800 96
      Another question that comes up all the time is about this $1 stuff and what a pain it is. So how to you avoid having to use $1? Use a list slice to assign $1 to a scalar without having to go via $1!
      my $_sensor_type = 'I2600*&^_A8699()^%#@C9800&*%A96'; my $type = ($_sensor_type =~ /[a-z]+([0-9]+)/i)[0]; print "$type\n"; #prints 2600 #so what happens if the match and consequent slice fails? $type ||= "some default"; #or check for undef
      There are lots of cases where this trick is handy. Some types of split scenarios can produce undef values and this special Perl operator ||= can override that to a value, like even "".
        Thank you for pointing out the significance of the /g identifier. I have removed it and my script is working as expected.