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

/

I am working on the match functionality and have come up with a problem. Below is code and error:

print "Enter a string: "; chomp(my $_ = <STDIN>); if ($_ = /([A|a])/) { my $afterstring = $'; print "This is the after string $afterstring\n"; if( $afterstring = /([B|b)/ ) { print The string has an a but also a following b\n"; } else { print "The string has an a , but not a following b\n"; } } else { print "String did not match\n"; }

And here is the error:

Uncaught exception from user code Unmatched [ in regex; marked by <-- HERE in m/([ <-- HERE B|b) +/ at Exercise_7_4.pl line 24.

TIA The Catfish

Replies are listed 'Best First'.
Re: match function
by Corion (Patriarch) on Jun 09, 2020 at 19:01 UTC

    What is your question?

    I think the error message is quite clear:

    Unmatched [ in regex; marked by <-- HERE in m/([ <-- HERE B|b)

    There is an unmatched opening square bracket in your regular expression.

    Your regular expression is

    /([B|b)/

    Maybe you wanted to write [Bb], or maybe ([B|b])? But that's not what you wrote.

    Also, the following code will most certainly not do what you think it does:

    if ($_ = /([A|a])/) {

    Most likely, you want to use the regex binding operator =~ and not the assignment operator =.

Re: match function
by choroba (Cardinal) on Jun 09, 2020 at 20:41 UTC
    Note also the missing double quote here:
    print The string has an a but also a following b\n"; # ^
    map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]
Re: match function
by BillKSmith (Monsignor) on Jun 09, 2020 at 22:50 UTC
    It is easier to test explicitly for what you want.
    use strict; use warnings; print "Enter a string: "; chomp ($_ = <>); my $msg = !/a/i ? 'String did not match' : !/a.*b/i ? 'The string has an a, but not a following b' : 'The string has an a, but also a following b' ; print $msg, "\n";

    UPDATE: Even better, use positive tests:

    my $msg = /a.*b/i ? 'The string has an a, and also a following b' : /a[^bB]*$/i ? 'The string has an a, but not a following b' : 'String did not match' ;
    Bill
Re: match function
by AnomalousMonk (Archbishop) on Jun 09, 2020 at 21:57 UTC

    Just for the sake of completeness...

    I think Corion has already alluded to this, but the  [a|A] character class consists in the '|' (pipe) and 'a' and 'A' characters. The  | regex alternation metacharacter is not meta inside a character class. See Bracketed Character Classes in perlrecharclass.


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

Re: match function
by Marshall (Canon) on Jun 10, 2020 at 20:13 UTC
    I liked all of the comments in this thread. I would add a cautionary note about the use of $'.
    In Perl versions <5.20 just this statement my $afterstring  = $'; can cause a huge regex performance penalty on every regex in the entire script, not just limited to where this variable is actually used. https://perldoc.perl.org/perlvar.html gives the gory details. This thread shows a number of ways to avoid using this special variable and I recommend doing so. Perl versions can remain in use for a surprisingly long time because Perl is integral to the operation of many OS's and there will be a default "system Perl" that is only updated in a very conservative way. There are plenty of Perl 5.8 installations still out there. I don't see any compelling reason to use $' in this example and would not do so.

      The "Performance issues" sub-section of perlvar that Marshall links to covers this of course, but I think it's worth emphasizing that the related variables  $` $& $' all have the same problem prior to Perl 5.20.


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