Beefy Boxes and Bandwidth Generously Provided by pair Networks
go ahead... be a heretic
 
PerlMonks  

regex return true instead of false

by ovedpo15 (Pilgrim)
on Aug 26, 2019 at 11:35 UTC ( [id://11105058]=perlquestion: print w/replies, xml ) Need Help??

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

Hi Monks, I have a string and I want to add something to it, if it does not already have it.
I though that the following code, should do it:
unless ($args =~ /\-rs(\s+)(\S+)/ && $args =~ /\-p(\s+)(\S+)/ && $args + =~ /\-P(\s+)(\S+)/) { $args .= " --rs $str"; }
The idea:
if ($args =~ /\-rs(\s+)(\S+)/ || $args =~ /\-p(\s+)(\S+)/ || $args =~ + /\-P(\s+)(\S+)/) { // do nothing } else { $args .= " --rs $str"; }
Then I understood that it should have the not operator before it:
unless (! $args =~ /\-rs(\s+)(\S+)/ && ! $args =~ /\-p(\s+)(\S+)/ && ! + $args =~ /\-P(\s+)(\S+)/) { $args .= " --rs $str"; }
But it still does not work as expected. My last guess is due to regex grouping but not sure what to do. How to solve it?

Replies are listed 'Best First'.
Re: regex return true instead of false
by haukex (Archbishop) on Aug 26, 2019 at 11:43 UTC

    The difference between your first and second examples is that you've swapped out the || for && operators. If you hadn't done that, it works - unless (condition) {code} is equivalent to if (condition) {} else {code} and if ( not (condition) ) {code}, but there is no change to condition needed.

    In the third example, due to operator precedence, !$var =~ /regex/ is equivalent to (!$var) =~ /regex/. Although you could use parentheses, the better way to write that is $var !~ /regex/. Also, you need to swap the unless for an if, since the question you're asking is "if $args doesn't contain this thing, and $args doesn't contain this other thing", not the opposite of this condition.

    Update: Tested some more, and added the last sentence.

Re: regex return true instead of false (precedence)
by LanX (Saint) on Aug 26, 2019 at 11:46 UTC
    your ! has higher precedence than =~ , please note the (parens) due to -p flag in B::Deparse

    d:\exp>perl -MO=Deparse,-p -e"if (! $args =~ /\-rs(\s+)(\S+)/ && ! $ar +gs =~ /\-p(\s+)(\S+)/ && ! $args =~ /\-P(\s+)(\S+)/){1}" if (((((!$args) =~ /\-rs(\s+)(\S+)/) and ((!$args) =~ /\-p(\s+)(\S+)/) +) and ((!$args) =~ /\-P(\s+)(\S+)/))) { '???'; } -e syntax OK

    I'd say either use not instead of ! or just !~ instaed of =~

    and I'd also recommend using and instead of &&

    EDIT

    you might be interested in reading

    Cheers Rolf
    (addicted to the Perl Programming Language :)
    Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

      The easiest way to get around precedence-issues is to define precedence yourself by using (a lot of) brackets. So

      unless (! $args =~ /\-rs(\s+)(\S+)/ && ! $args =~ /\-p(\s+)(\S+)/ && ! + $args =~ /\-P(\s+)(\S+)/) {
      will become
      unless ((!($args =~ /\-rs(\s+)(\S+)/)) && (!($args =~ /\-p(\s+)(\S+)/) +) && (!($args =~ /\-P(\s+)(\S+)/))) {
      I agree it looks a bit confusing, but modern editors help you by showing the matching bracket. And you don't have to think about rules (which might be counter-intuitive (like ! vs =~) or different in other programming languages).

      HTH, Rata

        I agree that it's better to over use brackets than forgetting them.

        On the other hand there's a good reason why Perl has that many operators.

        And, not, or won't bite you in Boolean expressions because they have the lowest precedence. (But I use brackets when combining them, I need a complicated mnemonic to remember that and has higher precedence than or)

        And !~ is really underused.

        Cheers Rolf
        (addicted to the Perl Programming Language :)
        Wikisyntax for the Monastery FootballPerl is like chess, only without the dice

        I prefer to use indenting to make all the parens more clear. Also, this "unless not" syntax can be confusing.
        I think I got this right, but it is easy to make a mistake. Consider:
        # X is the "default action" # do X with an exception that when A,B and C are all false # then don't do X unless (!A and !B and !C) {X} # if anybody is true then they all can't be false # so we do X unless anybody is true (meaning they # can't all be false) unless (A or B or C) {X} ------- unless ( (!($args =~ /\-rs(\s+)(\S+)/)) && (!($args =~ /\-p(\s+)(\S+)/)) && (!($args =~ /\-P(\s+)(\S+)/)) ) {..... # I figure this is easier to understand: unless ( $args =~ /\-rs(\s+)(\S+)/ or $args =~ /\-p(\s+)(\S+)/ or $args =~ /\-P(\s+)(\S+)/ ) {....
Re: regex return true instead of false
by Corion (Patriarch) on Aug 26, 2019 at 11:43 UTC

    Please edit your post and show us the values of $args that match and the values that don't match.

    Also, it looks as if you are trying to parse command line parameters. Have you looked at Getopt::Long?

Re: regex return true instead of false
by AnomalousMonk (Archbishop) on Aug 26, 2019 at 22:59 UTC

    Please note that if
        $args =~ /\-rs(\s+)(\S+)/ || $args =~  /\-p(\s+)(\S+)/ || $args =~  /\-P(\s+)(\S+)/
    actually works for your purposes, it can be simplified to
        $args =~ m{ - (?: rs | p | P) (\s+) (\S+) }xms
    or its negation
        $args !~ m{ - (?: rs | p | P) (\s+) (\S+) }xms
    and you need not torture your brain with De Morgan's laws. And (?: rs | p | P) could be further simplified to (?: rs | [pP]) although I find the first form a bit neater somehow.


    Give a man a fish:  <%-{-{-{-<

Re: regex return true instead of false
by jwkrahn (Abbot) on Aug 26, 2019 at 22:40 UTC

    It looks like you may need:

    if ( $args !~ /\-rs(\s+)(\S+)/ && $args !~ /\-p(\s+)(\S+)/ && $args !~ + /\-P(\s+)(\S+)/ ) { $args .= " --rs $str"; }

Log In?
Username:
Password:

What's my password?
Create A New User
Domain Nodelet?
Node Status?
node history
Node Type: perlquestion [id://11105058]
Approved by Corion
help
Chatterbox?
and the web crawler heard nothing...

How do I use this?Last hourOther CB clients
Other Users?
Others about the Monastery: (6)
As of 2024-04-19 07:00 GMT
Sections?
Information?
Find Nodes?
Leftovers?
    Voting Booth?

    No recent polls found