The London Perl and Raku Workshop takes place on 26th Oct 2024. If your company depends on Perl, please consider sponsoring and/or attending.


Number::Phone::NANP::Vanity - Calculate vanity score of a NANP phone number




 use Number::Phone::NANP::Vanity;
 # simple case
 my $number = Number::Phone::NANP::Vanity->new(number => '8005551234');
 my $score  = $number->calculate_score;
 # check against a list of words as well
 my $number = Number::Phone::NANP::Vanity->new(
    number     => '8005551234',
    dictionary => [qw/flowers florist roses/],
 my $score  = $number->calculate_score;
 # parses formatted numbers too
 my $number = Number::Phone::NANP::Vanity->from_string('+1-800-555-1234');
 # print formatted number
 print $number->number_formatted; # 800-555-1234
 # custom format
 print $number->number_formatted('(%s) %s-%s%s'); # (800) 555-1234



number: a full, clean, 10 digit number
dictionary: pass a reference to array containing a list of words you'd like to check the number against. (optional)
keypad_layout: pass a reference to hash containing an alternative keypad mapping. By default it uses International Standard layout. (optional)


Calculates and returns an integer score for the given number.


Returns the number in a provided format. The format is the same as sprintf. Default format is "%s-%s-%s%s" (800-555-1234).


First of all, some terminology:

NPA: area code, first 3 digits
NXX: exchange, the 3 digits following NPA
sub: subscriber part of the number, the last 4 digits
sub1: first 2 digits of the subscriber part
sub2: last 2 digits of the subscriber part


NPA (area code) portion of the number equals NXX (exchange) portion of the number.

E.g. 800-800-1234.

Gets 1 point.


Subscriber parts repeat.

E.g. 800-745-1212

Gets 1 point.


NXX portion has all repeating numbers.

E.g. 800-555-5678

Gets 2 points.


Subscriber portion has all repeating numbers.

E.g. 800-478-5555

Gets 3 points.


Both NXX and subscriber portions repeat.

E.g. 800-555-5555

Gets 5 points.


Sub1 has repeating numbers.

E.g. 800-478-2232

Gets 1 point.


Sub2 has repeating numbers.

E.g. 800-478-3222

Gets 1 point.


NXX and subscriber follow an ascending sequential number pattern.

E.g. 800-234-5678

Gets 3 points.


NXX and subscriber follow a descending sequential number pattern.

E.g. 800-765-4321

Gets 2 points.


Subscriber follows an ascending sequential number pattern.

E.g. 800-478-1234

Gets 1 point.


Subscriber follows a descending sequential number pattern.

E.g. 800-478-4321

Gets 1 point. I'd give it half, but don't want to get into decimals.


The last 3 pairs of digits repeat.

E.g. 800-5-121212

Gets 2 points.


Checks the entire number for 3 or more consequitive repeating digits.

E.g. 800-227-7771

There are 4 consequitive digits 7.

Gets 1 point for each repetition over 2 digits long. E.g. 1 point for 3 digits, 2 points for 4 digits.


The number matches a word provided via dictionary attribute. The words are checked in the order provided.

Score will be recorded upon first successful match. No further matching will be performed.

Matching is performed against the tail part of the word only.

Words with more than 7 letters are skipped.

Words with characters not contained in the keypad_layout are skipped.

Score is assigned based on the length of the word matched. One point is assigned for every letter matched above, and including a 3 character word. E.g.:

800-555-2FUN - 1 point (3 letter word matches)

800-555-PERL - 2 points (4 letter word matches)

800-55-LLAMA - 3 points (5 letter word matches)


You can also define your own custom rules by passing an anonymous sub to the add_rule method. The sub must return a score (int) equal or greater than zero. An optional second parameter can be returned as a string describing why the score was assigned.

 my $number = Number::Phone::NANP::Vanity->new(number => '8003141592');
 $number->add_rule(sub {
     return (10, "Toll Free Pi")
        if shift->number eq '8003141592';
 my $score = $number->calculate_score;




Due to the fluid nature of this module, the rules might be changed at any time. New rules might be added later on. Therefore you should not rely on the score being fair across multiple sessions. The score should be used to compare the number vanity during one session run. In other words, the score shall not be recorded and compared against in the future.


Roman F. <>


This software is copyright (c) 2011 by Roman F.

This is free software; you can redistribute it and/or modify it under the same terms as the Perl 5 programming language system itself.