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

Oops!im really sorry bout that. The code is mentioned below : -------------------------------------------
$_sensor_type = “I2600”; if($_sensor_type =~ /[a-z]+([0-9]+)/ig){ print "\n\n\n***Importing Original Action sens +or Configuration onto the ISM and pushing it onto the sensor model $1 + via API***\n\n\n"; my $out = `wget --no-check-certificate http:/ +/$_config_hash->{'database_ip'}/intruvert/jsp/sensorConfigImport.jsp? +params=$_config_hash->{'sentype'}:$_config_hash->{'sensor_ID'}:Hampi_ +$1_Master_Sigset.xml`; }
---------------------------------------------------
What im trying to do here is push an API depending on certain parameters.
The issue lies with the "if" statement in the beginning. The pattern match fails due to which i dnt get the value "2600" in $1.
However, this code is used in the starting of the program too where it works fine. The issue arises only when it is used the second time in the code.
Hope i've mentioned all the details required this time around :)

Replies are listed 'Best First'.
Re^3: Repeated Pattern Matching Fails
by jwkrahn (Abbot) on Jan 28, 2009 at 13:21 UTC

    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".

      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.

      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 "".
Re^3: Repeated Pattern Matching Fails
by Marshall (Canon) on Jan 28, 2009 at 13:37 UTC
    If you look closely at your "$_sensor_type =" statement, you will see that you have different kinds of quotes around "I2600". Notice the difference between them and the first quote in your print statement, ". forward leaning and backward leaning " are different than normal straight up ".

    I am surprised that this even compiles. Are you using warnings and strict?

    Other than that, I see no reason why I2600 shouldn't match the regex, although the /g is completely unnecessary here. I tested "I2600" on my machine and works great with proper quote characters.

    UPDATE: this is not the problem, it appears that previous use of string in an inappropriate global match was the issue..oooops. Although I must say that sometimes these non-printing and/or non-standard characters can and DO cause problems... that is not the case here..