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

  • For some reason, printing out $1 only prints 1 star when the regex $HAIR is clearly matching 3 stars
  • For some reason, my attempt to replace 3 stars at the start of a string with the empty string is clearning the whole string.

    Could someone please help me with this? Thanks!

    my @question; sub make_question { my ($question,@answer) = @_; [ $question, \@answer ]; } push @question, make_question 'What is an example of autovivification in Perl?', '***my %x; $x{y}->[2]->{jum} ;', 'sub y { my ($self,$x) = @_ }', 'my $end = ($end > rand) ? $end : rand;'; ; for (@question) { printf "Question %d: %s\n", ++$count, shift @$_; my $HAIR = '^([*]){3}'; my $count; for my $answer (@{$_->[0]}) { if ($mode eq 'key') { if ($answer =~ /$HAIR/) { $answer = $1; } else { $answer = ''; } } else { $answer = s/$HAIR//; } printf "\t%d. %s\n", ++$count, $answer; } print "\n"; }
  • Replies are listed 'Best First'.
    Re: regex to substitute 3 stars at beginnning of string with none?
    by Sprad (Hermit) on Apr 23, 2001 at 21:40 UTC
      Ready to kick yourself?

      Change $answer = s/$HAIR//; to $answer =~ s/$HAIR//;

      ---
      I'm too sexy for my .sig.

        Heehee, I missed that one... very important distinction :)
                        - Ant
        Thanks. That works perfectly.

        -- That light at the end of the tunnel is the headlights of an approaching train.

    Re: regex to substitute 3 stars at beginnning of string with none?
    by suaveant (Parson) on Apr 23, 2001 at 21:32 UTC
      '^([*]){3}' has the {3} on the outside of the (), so it is match ([*]} many times, each time saving a single *... you need to move them inside '^([*]{3})' then you will be happier.
                      - Ant
        Update: A quick test confirms what merlyn says below. I have to admit that the correct behavior surprised me, but sounds sensible in retrospect. Here's my original post, anyway:

        To clarify: ([*]){3} is like ([*])([*])([*])

        That means that $1, $2, $3 each contain one of the asterisk characters. The suggested solution ([*]{3}) has all three characters inside the same set of parentheses, and therefore saves them all into $1.

        buckaduck

    Re: regex to substitute 3 stars at beginnning of string with none?
    by Corion (Patriarch) on Apr 23, 2001 at 21:36 UTC

      $1 really matches only one star. If you want to capture all three stars in $1, you must use ^([*]{3}) (note that the {} quantifier has moved into the capturing parentheses).

    Re: regex to substitute 3 stars at beginnning of string with none?
    by princepawn (Parson) on Apr 23, 2001 at 21:38 UTC
      '^(*){3}' has the {3} on the outside of the (), so it is match (*} many times, each time saving a single *... you need to move them inside '^(*{3})' then you will be happier.
      For key mode, your answer is correct and I am indeed happier. However, for test mode (when the substitution is run on $HAIR, the whole string is still wiped out!