Format Phone Numbers

I’d like an extension that changes a selected string of characters into a standard format for a phone number (if exactly 10 digits other than the optional leading country code are in the string) and adds the county code with plus sign (“+”) if it is not already present.

Examples:

“(123) 456-7890” → “+1 123.456.7890”
“123-456-7890” → “+1 123.456.7890”
“123.456.7890” → “+1 123.456.7890”
“1234567890” → “+1 123.456.7890”
“+1123-456-7890” → “+1 123.456.7890”
“1 123-456-7890” → “+1 123.456.7890”
“123-456-789” → does nothing

Having a setting for different countries is icing on the cake; I personally need it for the United States only but having different rules for different countries would be very cool.

Thank you for reading this idea.

1 Like

Share the extension, if you don’t mind.

1 Like

I only know google/libphonenumber: Google’s common Java, C++ and JavaScript library for parsing, formatting, and validating international phone numbers to format phone numbers correctly. Surely using the whole library is overkill?

1 Like

Here’s my attempt on formatting phone numbers for countries that are members of the North American Numbering Plan, which includes the United States. I’ve included references to formatting phone numbers for other countries in case someone wants to extend it.

// #popclip
// name: US Phone Number
// icon: square +1
// language: javascript
// after: paste-result
//
// Authoritative sources on formatting phone numbers:
// https://en.wikipedia.org/wiki/North_American_Numbering_Plan (NANP)
// https://en.wikipedia.org/wiki/E.123
// https://en.wikipedia.org/wiki/E.164
//
// Programming resources
// https://stackoverflow.com/questions/15745545/is-there-a-standard-for-phone-numbers 
// https://github.com/google/libphonenumber
//
// Configuration Constants
const countryCode = '1';                // US and other NANP countries
const prefix = '+' + countryCode + ' '; // Plus sign (+) and space are required by E.123
const separator = ' ';                  // Spaces are default for E.123
const standardPhoneNumberLength = 10;   // Full number for US and other NANP countries (including area code)
//
// Get text selected by PopClip
const selectedText = popclip.input.text;
//
// Remove all non-digit characters and countryCode, if any, from selectedText 
let digitsOnly = selectedText.replace(/\D/g, '');
if (digitsOnly.startsWith(countryCode)) {
 digitsOnly = digitsOnly.slice(countryCode.length);
}
// If the digits are the exact length of a standard phone number, return digits formatted with countryCode
if (digitsOnly.length == standardPhoneNumberLength) {
return prefix + digitsOnly.slice(0,3) + separator + digitsOnly.slice(3,6) + separator + digitsOnly.slice(6);
} 
//
// Otherwise do nothing
return selectedText;
1 Like

This is exactly what I came to the forum looking for!

I copied the example, saved it in text file ending .popcliptxt and was able to customize as needed.

Thank you!!!

1 Like

Allen:

Please share your customizations if they might apply to others.

Thank you.

  • nello
1 Like
#popclip
name: Format US Phone
icon: symbol:phone
requirements: [text, paste]
actions:
- regex: (?:\+?1[\s\-]?)?\(?(\d{3})\)?[\s\.\-]?(\d{3})[\s\.\-]?(\d{4})
  javascript: |
    var input = popclip.input.text.trim();
    var re = /(?:\+?1[\s\-]?)?\(?(\d{3})\)?[\s\.\-]?(\d{3})[\s\.\-]?(\d{4})/;
    var m = re.exec(input);
    popclip.pasteText(m ? '+1 ' + m[1] + '.' + m[2] + '.' + m[3] : input);
    popclip.showText('Phone number is copied.');

I was digging around in the tools I’m working with, trying to get them to realize that ( and ) are NOT the way.

We settled on E.164, which would beg this minimal set of changes:

-const separator = ' ';                  // Spaces are default for E.123
+const separator = '-';                  // Spaces are frowned upon in E.164
-const prefix = '+' + countryCode + ' '; // Plus sign (+) and space are required by E.123
+const prefix = '+' + countryCode + '-'; // Plus sign (+) is required by E.123, the - is suggested by E.164

So, my version is largely the same as yours, but set the separator first and uses it in the prefix

phone.popcliptxt

// #popclip
// name: US Phone Number
// icon: square +1
// language: javascript
// after: paste-result
//
// Authoritative sources on formatting phone numbers:
// https://en.wikipedia.org/wiki/North_American_Numbering_Plan (NANP)
// https://en.wikipedia.org/wiki/E.123
// https://en.wikipedia.org/wiki/E.164
//
// Programming resources
// https://stackoverflow.com/questions/15745545/is-there-a-standard-for-phone-numbers 
// https://github.com/google/libphonenumber
//
// Authored by Nello + Allen
// https://forum.popclip.app/t/format-phone-numbers/1536
//
// Configuration Constants
const countryCode = '1';                // US and other NANP countries
const prefix = '+' + countryCode;       // Plus sign (+) is required by E.123
const prefixSeparator = '-'             // A space ' ' is required by E.123, a '-' dash is suggested by E.164
const bodySeparator = '-';              // Use spaces  ' '  for E.123 format, use a  '-' dash for E.164
const standardPhoneNumberLength = 10;   // Full number for US and other NANP countries (including area code)
//
// Get text selected by PopClip
const selectedText = popclip.input.text;
//
// Remove all non-digit characters and countryCode, if any, from selectedText 
let digitsOnly = selectedText.replace(/\D/g, '');
if (digitsOnly.startsWith(countryCode)) {
 digitsOnly = digitsOnly.slice(countryCode.length);
}
// If the digits are the exact length of a standard phone number, return digits formatted with countryCode
if (digitsOnly.length == standardPhoneNumberLength) {
return prefix + prefixSeparator + digitsOnly.slice(0,3) + bodySeparator + digitsOnly.slice(3,6) + bodySeparator + digitsOnly.slice(6);
} 
//
// Otherwise do nothing
return selectedText;

Thank you for doing the hard work here!
And thankfully, I didn’t have to bother adding a conditional to use parenthesis :sweat_smile:

2 Likes