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

In the statement below ... 1. What does the (!~) mean? 2. What do the forward slashes mean around (not stop)?

if($CPC_stop_type[$i] !~ /not stop/){

Replies are listed 'Best First'.
Re: Forward slashes around argument
by haukex (Archbishop) on Jul 01, 2019 at 17:49 UTC
    In the statement below ... 1. What does the (!~) mean? 2. What do the forward slashes mean around (not stop)? if($CPC_stop_type[$i] !~ /not stop/){

    The !~ operator basically means "does not match", on its left-hand side is the thing being matched against (usually a string), and on its right-hand side is the thing doing the matching, such as a regular expresion. /not stop/ is a regular expression (regex) that looks for the characters not stop (this particular regex does not contain any characters that have a special meaning in regexes). In English, that line of code reads as "If the $ith element of the array @CPC_stop_type does not contain the sequence of characters not stop, then ..."

      I thought that the forward slashes were for characters with special meaning. But if I use the /.../, then the error I coded is displayed properly like it should. ($CPC_stop_type $i = "power-off stop")

      if($CPC_stop_type[$i] !~ /not stop/){

      - CPC SafeZone 1 FENCE
      - ERROR: "Stop Type" must be "Not Stop" for PLC Controlled spaces (1-7).

      If I do not use the /.../, it will not display the error when it still equals "power-off stop".

      if($CPC_stop_type[$i] !~ not stop){

      - CPC SafeZone 1 FENCE
      - PASSED

        I thought that the forward slashes were for characters with special meaning.

        Technically, the forward slashes are known as the m// operator, and anything between the delimiters (in this case slashes) is a regular expression. In a regular expression, some characters have special meaning, such as .*?, and others do not - mostly the "word" characters such as a-zA-Z0-9 and so on. Such characters are matched literally, so /not stop/ just means to look for the eight characters not stop.

        if($CPC_stop_type[$i] !~ not stop){

        If you're using strict, as one generally should, that's thoeretically valid Perl if you've got a sub stop - but I doubt this statement makes sense. If you're not using strict, that's valid Perl, because not is an operator and stop is taken as a so-called "bareword", but that's getting into details that probably aren't relevant here.

        As for the rest of your question, sorry, but I don't understand what you are trying to do. If you want to check whether a string...

        • contains not stop, use $string =~ /not stop/.
        • doesn't contain not stop, use $string !~ /not stop/.
        • is exactly "not stop", use $string eq "not stop".
        • is not exactly "not stop", use $string ne "not stop".

        There are of course additional options - if you wanted to express "does this string contain not stop or power-off stop", you could write that as $string =~ /(?:power-off|not) stop/.

        If things aren't working as you expect, then please see How do I post a question effectively? and Short, Self-Contained, Correct Example: Please provide a short, runnable piece of code that demonstrates the problems you're having, along with short but representative sample input, the expected output for that input, the actual output you're getting, including any error messages, each within <code> tags.

Re: Forward slashes around argument
by GrandFather (Saint) on Jul 01, 2019 at 21:10 UTC

    You may be confusing / with \ (back slash). Back slash is used in may languages to "escape" a following character to alter the character's meaning. For example you can use \ to quote a " in a string so that the " doesn't terminate the string: my $str = "The coder said \"This string is quoted\".";.

    Optimising for fewest key strokes only makes sense transmitting to Pluto or beyond
Re: Forward slashes around argument
by Marshall (Canon) on Jul 02, 2019 at 02:15 UTC
    The forward slashes are signify a "regular expression". Regular Expressions. A regex can match a series of characters within a variable and much, much more than that. Be careful with syntax like "if this variable doesn't match 'not stop'" - that is a double negative and is hard to understand.

    Update: italics added to main point. Extraneous \ removed before single quotes.

    use strict; use warnings; my @CPC_STP_type =('bus does not stop here','bus stop', 'anything', 'n +ot this stop'); foreach my $type (@CPC_STP_type) { if ($type =~ m/not stop/) #the "m" is optional { print "type=$type......'not stop' detected\n"; } else { print "type=$type......'not stop' was NOT detected\n"; } } print "\n"; =prints type=bus does not stop here......'not stop' detected type=bus stop......'not stop' was NOT detected type=anything......'not stop' was NOT detected type=not this stop......'not stop' was NOT detected =cut foreach my $type (@CPC_STP_type) { if ($type !~ m/not stop/) #the "m" is optional { print "type=$type......We stop here\n"; } else { print "type=$type......We keep going\n"; } } __END__ #watch out for the unexpected! type=bus does not stop here......We keep going type=bus stop......We stop here type=anything......We stop here type=not this stop......We stop here <= Whoa!!
      print "type=$type......\'not stop\' detected\n";

      You might be pleased to hear that those backslashes before the single-quotes are superfluous. If you omit them your code will become shorter to type and simpler to eye-parse:

      print "type=$type......'not stop' detected\n";

      HTH.

        You are quite correct.
        My point was: Be careful with syntax like "if this variable doesn't match 'not stop'" - that is a double negative and is hard to understand..

        Perl quoting can become hard to understand. An extraneous \ in this case makes little difference, but thanks for pointing that out.

Re: Forward slashes around argument
by Anonymous Monk on Jul 04, 2019 at 20:49 UTC

    Hi

    ppi_dumper is great at hints

    $ ppi_dumper foo.pl PPI::Document PPI::Statement::Compound PPI::Token::Word 'if' PPI::Structure::Condition ( ... ) PPI::Statement::Expression PPI::Token::Symbol '$CPC_stop_type' PPI::Structure::Subscript [ ... ] PPI::Statement::Expression PPI::Token::Symbol '$i' PPI::Token::Whitespace ' ' PPI::Token::Operator '!~' PPI::Token::Whitespace ' ' PPI::Token::Regexp::Match '/not stop/' PPI::Structure::Block { ... } PPI::Token::Whitespace '\n'

    So lets see, a Token::Operator ... Regexp::Match ... journey begins at perlop