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

I need to find two consecutive occurrences of a given character. The following SSCCE works ('cc' matches, 'cz' does not match), but I have to turn off 'uninitialized' warnings prior to the regex to make it work without getting 'uninitialized' warning messages about $1. Do you know a better way to do this, preferrably without the need to suppress warnings?

On a side note, the "start of string" anchor (^) in the regex is fine, but if I add an "end of string" anchor to the regex (either '$' or '\z') the match fails. The match should not fail with the addition of an "end of string" anchor, because each string is exactly 2 characters long.

Where is Jeffrey Friedl when you need him? (ha ha) :-)

#!/usr/bin/perl use strict; use warnings; my @txt = ('cc','cz'); for (@txt) { no warnings 'uninitialized'; if (m/^(.)$1/) { print "True \$_ = |$_| \$1 = |$1|\n"; } else { print "False \$_ = |$_| \$1 = |$1|\n"; } use warnings; }

"It's not how hard you work, it's how much you get done."

Replies are listed 'Best First'.
Re: How To Remove Warnings From Regex
by Athanasius (Archbishop) on Feb 04, 2024 at 04:22 UTC

    Hello roho,

    Change $1 to \1 within the regex:

    use strict; use warnings; my @txt = ('cc', 'cz'); for (@txt) { if (m/^(.)\1$/) { print "True \$_ = |$_| \$1 = |$1|\n"; } else { print "False \$_ = |$_| \$1 = |$1|\n"; } }

    Output:

    14:13 >perl 2092.SoPW.pl True $_ = |cc| $1 = |c| False $_ = |cz| $1 = |c| 14:14 >

    As you can see:

    • warnings are gone
    • the closing $ is OK now
    • $1 is no longer the empty string on match fail, but is rather the captured character “c”.

    See e.g. Capture groups.

    Hope that helps,

    Athanasius <°(((><contra mundum סתם עוד האקר של פרל,

      Thank you Athanasius! That works perfectly. For as long as I can remember, I've avoided the backslash numbers in favor of the dollar-sign numbers, but I see in this case that is exactly what is called for. Thanks again.

      "It's not how hard you work, it's how much you get done."

        \1 works inside the regex where the capture group was defined. $1 works everywhere else, i.e. in a replacement of a substitution. $1 in a regex refers to a previously matched regex (which explains the uninitialized warnings).

        map{substr$_->[0],$_->[1]||0,1}[\*||{},3],[[]],[ref qr-1,-,-1],[{}],[sub{}^*ARGV,3]