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

so i asked a while ago for an regex alternative to substr.. here is 1 of the replies:
$string = "hello world"; print $string =~ /^.{1}(.{5})/;
also i know that !$! = 1, so i tried this:
$string = "hello world"; print $string =~ /^.{!$!}(.{5})/;
that would produce an empty line, why? I have tried many different ways but seems im restricted to using digits. just out of curiosity, why cant i do this?

Replies are listed 'Best First'.
Re: weird regex question
by kennethk (Abbot) on Apr 25, 2012 at 16:17 UTC

    You can get an explanation of any regular expression using YAPE::Regex::Explain. In this case, it outputs:

    The regular expression: (?-imsx:^.{!}(.{5})) matches as follows: NODE EXPLANATION ---------------------------------------------------------------------- (?-imsx: group, but do not capture (case-sensitive) (with ^ and $ matching normally) (with . not matching \n) (matching whitespace and # normally): ---------------------------------------------------------------------- ^ the beginning of the string ---------------------------------------------------------------------- . any character except \n ---------------------------------------------------------------------- {!} '{!}' ---------------------------------------------------------------------- ( group and capture to \1: ---------------------------------------------------------------------- .{5} any character except \n (5 times) ---------------------------------------------------------------------- ) end of \1 ---------------------------------------------------------------------- ) end of grouping ----------------------------------------------------------------------

    The issue is that the $! variable is interpolated to an empty string but ! operator doesn't get interpolated as such in the regular expression. Essentially, your modification is actually looking for the string literal {!}.

    #11929 First ask yourself `How would I do this without a computer?' Then have the computer do it the same way.

Re: weird regex question
by JavaFan (Canon) on Apr 25, 2012 at 16:25 UTC
    If you use !$!, only $! get interpolated, not the entire expression. In your case, $!, in string context, will be the empty string. So, you end up with
    /^.{!}(.{5})/
    which is not going to match. If you want to interpolate the expression, use:
    /^.{@{[!$!]}}(.{5})/
      hmm kinda makes sense, so how would i do the 5?
        What do you mean, how would I do the 5?
        1 and 5
        my $string = "hello world"; print $string =~ /^.{@{[!$[]}}(.{${\($]<<$]>>$])}})/; # 'ello '
        or print $]>>$?;