http://www.perlmonks.org?node_id=1021351

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

Hi Monks,

What does "\z" mean in Perl?

I have a question about grep function. For the code below:

my @new_array = grep(/^\s+\d+\s+/, @array, $number);

What's the variable "$number" for? I remember grep only takes two input variables, one is the expression and the other one is an array.

Thanks!

Dicty

  • Comment on regular expression and grep function questions

Replies are listed 'Best First'.
Re: regular expression and grep function questions
by kcott (Archbishop) on Mar 02, 2013 at 00:49 UTC

    G'day dicty,

    \z is used in regular expressions as an anchor to match the end of a string (which could be multi-line). It differs from $ which matches the end of a line; and, it is subtly different from \Z (uppercase Z) which matches the end of the string but optionally before a newline if one exists.

    The following code demonstrates each of these differences:

    $ perl -Mstrict -Mwarnings -E ' my $string = "abc\ndef\n"; $string =~ /(.*?)$/ms; say q{[$]}, $1, q{[$]}; $string =~ /(.*?)\z/ms; say q{[z]}, $1, q{[z]}; $string =~ /(.*?)\Z/ms; say q{[Z]}, $1, q{[Z]}; ' [$]abc[$] [z]abc def [z] [Z]abc def[Z]

    Under perlre - Regular Expressions, $ is described in the Metacharacters section and \z and \Z are described in the Assertions section.

    I see hippo has answered your second question.

    -- Ken

Re: regular expression and grep function questions
by hippo (Bishop) on Mar 01, 2013 at 23:18 UTC

    Consider the general form:

    some_sub($foo, @bar, $baz);

    How would perl know when @bar ends and $baz begins? Actually, it cannot. So, one can suppose that the argument list is equivalent to these scalars:

    $foo, $bar[0], $bar[1], $bar[2], ..., $bar[n], $baz

    So, there is no great significance to your $number other than it is appended to the end of the argument list.

Re: regular expression and grep function questions
by 7stud (Deacon) on Mar 02, 2013 at 07:35 UTC

    What does "\z" mean in Perl?

    Some people use the flags /xms as the default starting point for every regex. If you do that, then:

    \A  \z   --beginning and end of the entire string
    ^   $    --beginning and end of a "line" within the string
    

    Then just forget about \Z, which is unnecessary.

    use strict; use warnings; use 5.010; my $string = "HELLO\nWORLD\nGOODBYE"; my @patterns = ( '\A (.)', #Match start of entire string followed by any char '^ (.)', #Match start of every line followed by any char '(.) \z', #Match any char followed by end of the entire string '(.) $', #Match any char followed by end of a line ); for my $pattern (@patterns) { my @matches = $string =~ /$pattern/gxms; say "@matches"; say '*' x 20; } --output:-- H ******************** H W G ******************** E ******************** O D E ********************

    I remember grep only takes two input variables, one is the expression and the other one is an array.

    Actually,

    grep BLOCK LIST
    

    A list is a series of comma separated values, e.g. 1, 'a', 2, 'b'. So if you give perl an array along with a scalar value in a spot where perl expects a list, then perl extracts the values from the array and adds the scalar value to the end, creating one list.

    That phenomena happens in a lot of places in perl. As hippo explained, look what happens if you call a sub with two arrays:

    use strict; use warnings; use 5.010; sub do_stuff { my @x = shift; my @y = shift; say "@x"; say "@y"; } my @arr1 = (10, 20); my @arr2 = ('a', 'b'); do_stuff(@arr1, @arr2);

    What do you expect the output to be?

    When you call the function perl 'unwinds' the first array into a list of comma separated values, and perl does the same with the second array, creating one big list--as if you called the function like this:

    do_stuff(10, 20, 'a', 'b');

    That list then gets assigned to the array named @_. So when you shift one value from @_ and assign the value to the array @x, it's as if you wrote:

    my @x = 10;

    And in that line, because there is an array on the left, which expects a list on the right, perl converts the scalar 10 to the list (10) giving you this:

    my @x = (10);