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

Using the substring function to parse out NPA-NXX of phone numbers in records, where sometimes the phone number starts with a "1" (11 characters/digits in length), and sometimes they don't (10 characters/digits in length). Using the following syntax to 1) print my original field and 2) print a substr, starting 10 characters from the END of a the string (negative index), and parse out 6 characters (and even filtering out ONLY for records where there are only 11 characters):

if(length($11)==11){print $11, (substr($11,-10,6))

But the results I get have the results starting from the very first characters in the string:

15556667777 155566

I am not sure what I am doing wrong?

Replies are listed 'Best First'.
Re: Negative Index with "substr" Not Working
by BrowserUk (Patriarch) on Nov 23, 2015 at 20:20 UTC

    Works for me?

    $s = '01234567890';; print substr $s, -10, 6;; 123456 $s = '15556667777';; print substr $s, -10, 6;; 555666

    With the rise and rise of 'Social' network sites: 'Computers are making people easier to use everyday'
    Examine what is said, not who speaks -- Silence betokens consent -- Love the truth but pardon error.
    "Science is about questioning the status quo. Questioning authority". I knew I was on the right track :)
    In the absence of evidence, opinion is indistinguishable from prejudice.
Re: Negative Index with "substr" Not Working
by AnomalousMonk (Archbishop) on Nov 23, 2015 at 21:51 UTC

    Another way:

    c:\@Work\Perl\monks>perl -wMstrict -le "for my $s (qw(15556667777 3334445555 999999999 88888888 121212121 +212)) { printf qq{'$s' -> }; my ($npa, $nxx) = $s =~ m{ \A 1? (\d{3}) (\d{3}) \d{4} \Z }xms; print defined($nxx) ? qq{npa '$npa', nxx '$nxx'} : 'invalid number' +; } " '15556667777' -> npa '555', nxx '666' '3334445555' -> npa '333', nxx '444' '999999999' -> invalid number '88888888' -> invalid number '121212121212' -> invalid number
    Please see perlre, perlretut, and perlrequick.

    Update: This approach to parsing is open to further regexish elaboration (I took a quick look at WP for NPA and NXX definitions, but I'm sure it's more involved):

    c:\@Work\Perl\monks>perl -wMstrict -le "my $rx_npa = qr{ [2-9] (?! 11) \d\d }xms; my $rx_nxx = qr{ [2-9] (?! 11) \d\d }xms; my $rx_subs = qr{ \d{4} }xms; ;; for my $s (qw( 15556667777 x15156667777 15516667777x x15556167777x 3334415555 x3134145555 3314415555x x3334445555x 999999999 x999999999 999999999x x999999999x 88888888 x88888888 88888888x x88888888 121212121212 x121212121212 121212121212x x121212121212x 5119999999 15119999999 9995119999 19995119999 )) { printf qq{'$s' -> }; my $got_pn = my ($npa, $nxx, $subs) = $s =~ m{ (?<! \d) 1? ($rx_npa) ($rx_nxx) ($rx_subs) (?! \d) }xms; print $got_pn ? qq{npa '$npa', nxx '$nxx', subscriber '$subs'} : 'n +o number'; } " '15556667777' -> npa '555', nxx '666', subscriber '7777' 'x15156667777' -> npa '515', nxx '666', subscriber '7777' '15516667777x' -> npa '551', nxx '666', subscriber '7777' 'x15556167777x' -> npa '555', nxx '616', subscriber '7777' '3334415555' -> npa '333', nxx '441', subscriber '5555' 'x3134145555' -> npa '313', nxx '414', subscriber '5555' '3314415555x' -> npa '331', nxx '441', subscriber '5555' 'x3334445555x' -> npa '333', nxx '444', subscriber '5555' '999999999' -> no number 'x999999999' -> no number '999999999x' -> no number 'x999999999x' -> no number '88888888' -> no number 'x88888888' -> no number '88888888x' -> no number 'x88888888' -> no number '121212121212' -> no number 'x121212121212' -> no number '121212121212x' -> no number 'x121212121212x' -> no number '5119999999' -> no number '15119999999' -> no number '9995119999' -> no number '19995119999' -> no number


    Give a man a fish:  <%-{-{-{-<

      Try regex

      sub test { my $str =shift; if(length($str)==11) { $str=~ m/^(\d(\d{6})\d+)$/; print"$1 $2\n"; } else { $str=~ m/^((\d{6})\d+)$/; print"$1$2 $2\n"; } } my $a='01234567890'; my $b ='15556667777'; test($a); test($b);

      Output 01234567890 123456
      15556667777 555666

        Be careful with (ie. don't use) the $a and $b operands... they are special to perl.

        my $x ='01234567890'; my $y ='15556667777'; test($x); test($y);
Re: Negative Index with "substr" Not Working
by Discipulus (Canon) on Nov 23, 2015 at 21:12 UTC
    your error must coming from elsewhere..
    perl -e "if(length($ARGV[0])==11){print $ARGV[0], (substr($ARGV[0],-10 +,6))}" 1234567890_ 1234567890_234567
    Anyway you presented few stroke of your code and it is impossible to tell if $11 come from the 11th capturing group of a regex or is very bad choice for a variable name: it is a special variable.

    the code above acts as you expect?

    L*
    There are no rules, there are no thumbs..
    Reinvent the wheel, then learn The Wheel; may be one day you reinvent one of THE WHEELS.
Re: Negative Index with "substr" Not Working
by GrandFather (Saint) on Nov 23, 2015 at 23:45 UTC

    The result you show can not be generated by the print statement you give (the print as given wouldn't generate the space between numbers). Show us a complete test script the demonstrates the issue you see.

    Is it possible that you are calling other code between the regex that sets $11 and the point where you use the value and that that code alters $11's contents?

    Premature optimization is the root of all job security