panthro
panthro

Reputation: 24061

Formatting a phone number in specific way?

This is not a duplicate, the linked thread does not explain how to achieve this.

I'm looking to get a phone number in a specific format.

+xx (x) xxx xxx xxxx

The user could type anything in (but should always be a +61 number). So far I have tried the below.

My question, is - is there a way to simply the below to perhaps one expression?

    value = value.replace(/\D/g,'');
    value = value.startsWith(0) ? value.substring(1) : value;
    value = value.startsWith('610') ? value.substring(3) : value;
    value = value.startsWith('61') ? value.substring(2) : value;
    value = '+61 (0) ' + value.replace(/\d{3,4}?(?=...)/g, '$& ');

Upvotes: 0

Views: 2337

Answers (2)

The fourth bird
The fourth bird

Reputation: 163207

You might match the number using:

^.*?\+?0*610?(\d{3})(\d{3})(\d{4})(?!\d).*$

Regex demo

And replace with:

+61 (0) $1 $2 $3

Explanation

  • ^ Assert the start of the string
  • .*? Match 0+ characters non greedy
  • \+? Match an optional plus sign
  • 0*610? Match 0+ times a zero, 61 with optional zero
  • (\d{3})(\d{3})(\d{4}) match 3 groups with 3, 3, and 4 digits
  • (?!\d) Negative lookahead to assert what follows is not a digit
  • .* Match 0+ characters
  • $ Assert the end of the string

const strings = [
  "xgsh6101231231234vvajx",
  "xgsh06101231231234vvajx",
  "xgsh000006101231231234vvajx",
  "+6101231231234",
  "xgsh61012312312345vvajx",
  "xgsh5101231231234vvajx",
  "xgsh00000101231231234vvajx",
  "xgsh6143545626455345601231231234vvajx"
];
let pattern = /^.*?\+?0*610?(\d{3})(\d{3})(\d{4})(?!\d).*$/;

strings.forEach((s) => {
  console.log(s.replace(pattern, "+61 (0) $1 $2 $3"));
});

Upvotes: 0

jjspace
jjspace

Reputation: 187

To expand and explain on @splash58's comment they propose using two regular expressions to do the full replacement you desire. The first(/\D|(0+|610|61)/gi) will remove all unwanted characters within the string. The second (/(\d{3})(\d{3})(\d{4})/gi) will take the remaining digits and capture the desired groupings so you can format them as desired. I highly suggest looking at the regex101 links they provided as that site will fully explain how and why a given expressions matches what it does on the right.

Short version:

/\D|(0+|610|61)/gi will match any NON-digit character OR a string of 0s, "610" or "61". Replace this with nothing to remove

/(\d{3})(\d{3})(\d{4})/gi will match a string of 10 digits and capture groups, that's what the parentheses are, of 3 digits, 3 digits and 4 digits. These can be referenced in the replacement as identifiers $1, $2 and $3 according to their position.

Putting it all together:

// look in a string and return formatted phone number only
function phone(str) {
    str = str.replace(/\D|(0+|610|61)/gi, '');
    str = str.replace(/(\d{3})(\d{3})(\d{4})/gi, '+61 (0) $1 $2 $3');
    return str;
}
console.log(phone('xgsh6101231231234vvajx'));
console.log(phone('+6101231231234'));

I would also recommend first doing a search on the entire input string for a series of numbers or whitespace so that you end up with less false positives. This can be done with a regular expression like /[\d\s]+/

Upvotes: 1

Related Questions