http://qs1969.pair.com?node_id=660160

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

SOLVED Can someone please tell me how to print the last two characters on the end of a string.

1234,Dr,Huxtable,Cliff,M,24/12/1976,60

Here is my pattern match

$sight = ($_ !~ m/\Z{2}/);

Thanks. Thanks Everybody

Replies are listed 'Best First'.
Re: Printing last two characters
by FunkyMonk (Chancellor) on Jan 03, 2008 at 11:26 UTC
    I wouldn't use a regexp, I'd use substr:
    print substr "1234,Dr,Huxtable,Cliff,M,24/12/1976,60", -2, 2; #Output: 60

    The second argument is the start position, with negative numbers mean from the end of the string and the third argument is how many characters to extract.

      Note that
      substr($str, -2, 2)
      can also be written as
      substr($str, -2)
      since substr defaults to extracting the rest of the string.

Re: Printing last two characters
by bart (Canon) on Jan 03, 2008 at 11:46 UTC
    \Z is an assertion or anchor, it matches at a position (the end of the string, or in front of a final newline — you probably ment to use \z instead), but it doesn't match anything with a nonzero length. And then you're asking, with {2}, to match it twice... or rather, you're asking it not to match. It's all very confusing. I'm sure you're feeling that way... :)

    What you should try to match, is two characters, followed by the end of the string. I can do it like this:

    /..\z/
    with capturing parens to capture these two characters:
    /(..)\z/
    or maybe like this:
    /(.{2})\z/
    After it matches, you can read the captured value out of $1, or you can put it directly into a variable like this:
    ($sight) = /(.{2})\z/;
    which will leave $sight undefined if it fails to match. Note the parens on the left, it tells the assignment operator = it's being called in list context, so the regexp returns a list of captures, and it assigns the first item in the returned list to the variable $sight.

    HTH.

Re: Printing last two characters
by reasonablekeith (Deacon) on Jan 03, 2008 at 11:40 UTC
    Firstly, you don't need a regex to pull the last two characters off your data. Use substr instead...
    my $string = "1234,Dr,Huxtable,Cliff,M,24/12/1976,60"; my $last_two_chars = substr($string, -2, 2); print $last_two_chars . "\n";
    Secondly, as you're passing comma delimited data, just pulling two chars seems over simplified, best to split it by comma (assuming no commas in your data, see Text::CSV for better parsing), give your columns some proper names, and access your data in a readable fashion...
    my $temp_col_id = 0; my %COLUMN_IDS_BY_NAME = map {$_, $temp_col_id++} qw(num1 title surnam +e firstname sex dob num2); my @split_data = split /,/, $string; print $split_data[$COLUMN_IDS_BY_NAME{num1}] . "\n"; print $split_data[$COLUMN_IDS_BY_NAME{title}] . "\n"; print $split_data[$COLUMN_IDS_BY_NAME{firstname}] . "\n"; # etc...
    ---
    my name's not Keith, and I'm not reasonable.
Re: Printing last two characters
by moritz (Cardinal) on Jan 03, 2008 at 11:41 UTC
    The best solution using substr was already posted, so let me just add an explanation why m/\Z{2}/ doesn't work.

    \Z matches not a character, but a position. So it's useless to say "match end of the string, and then again end of the string".

    With warnings enabled perl would have told you:

    Quantifier unexpected on zero-length expression in regex; marked by <-- HERE in m/\Z{2} <-- HERE / at -e line 1.
Re: Printing last two characters
by olus (Curate) on Jan 03, 2008 at 11:36 UTC
    If you want a regexp, this will work
    /(.{2})$/
    The '$' means the end of the string.
    perl -le 'my $str="qwerty"; $str=~m/(.{2})$/; print $1;' #output ty
Re: SOLVED Printing last two characters
by Slug (Acolyte) on Jan 03, 2008 at 11:49 UTC
    Thanks everyone, the response was overwhelming.

    I can see I'm going to like this forum.