-2

I have a problem: I need to get a phone number as a string "79991111111" and convert it to this type of string "+7 (999) 111-11-11".

As i got it i'm able to do it by using a String.format() - but in this case I need a string initially, but i know only format of expected string that comes by parameters (ex. "79991111111"), but not the exact string.

Summary: I need do "+7 (999) 111-11-11" from "79991111111" and there is difference values all the time, but the same type and length.

I tried to do it via regex, but i don't know how to change string with using regex

3
  • 1
    Welcome to Stack Overflow. Please take the tour to learn how Stack Overflow works and read How to Ask or how to improve the quality of your question. Then edit your question to include your full source code you have as a minimal reproducible example, which can be compiled and tested by others. Included sources should be in text format, not an image. Currently you are not asking any question. Commented Aug 23, 2023 at 21:37
  • 2
    If you use regular expressions, be careful about international prefixes: In your example, the prefix is just one digit long ("7"), but you must take in account that there are two-digit and even three-digit prefixes. To solve that, you might prepend zeroes at the begginning to fix the input string length to 13. Commented Aug 23, 2023 at 21:50
  • Adding to what @LittleSanti said, the "+7" in this example is a country calling code. Not only can the length of the country calling code vary (eg: +7 vs +44 vs +592), but the length and format of the number that comes after it also depends on the country code in use (eg: +1 uses the format "+1 (XXX) XXX-XXXX" while +86 uses the format "+86 XXX XXXX XXXX"). Commented Aug 23, 2023 at 22:06

3 Answers 3

4

Make use of MaskFormatter, for example...

MaskFormatter mf = new MaskFormatter("+# (###) ###-##-##");
mf.setValueContainsLiteralCharacters(false);
System.out.println(mf.valueToString("79991111111"));

which will output +7 (999) 111-11-11

Update

You should take a look at Googles libphonenumber - as formatting phone numbers does not have a simple solution

(ps - I've never used this before, this is all experimental on my part)

So, based on the documented examples, you could do something like...

// I had to add the `+` prefix, otherwise the parsing would fail
String input = "+79991111111";
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
    Phonenumber.PhoneNumber phoneNumber = phoneUtil.parse(input, CountryCodeSource.UNSPECIFIED.name());
    System.out.println(phoneNumber);
    System.out.println(phoneUtil.format(phoneNumber, PhoneNumberFormat.INTERNATIONAL));
    System.out.println(phoneUtil.format(phoneNumber, PhoneNumberFormat.NATIONAL));
    System.out.println(phoneUtil.format(phoneNumber, PhoneNumberFormat.E164));
} catch (NumberParseException e) {
    System.err.println("NumberParseException was thrown: " + e.toString());
}

And this will print ...

+7 999 111-11-11
8 (999) 111-11-11
+79991111111

At this point you "should" be able to walk away, as these are using "standardised" formats, but, if you need to do something "special", you could make use of PhoneNumberUtil#formatByPattern, which might look something like...

String input = "+79991111111";
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
try {
    NumberFormat newNumFormat = new NumberFormat();
    newNumFormat.setPattern("(\\d{3})(\\d{3})(\\d{2})(\\d{2})");
    newNumFormat.setFormat("($1) $2-$3-$4");

    List<NumberFormat> newNumberFormats = new ArrayList<NumberFormat>();
    newNumberFormats.add(newNumFormat);

    String formatted = phoneUtil.formatByPattern(phoneNumber, PhoneNumberFormat.INTERNATIONAL, newNumberFormats);
    System.out.println(formatted);
} catch (NumberParseException e) {
    System.err.println("NumberParseException was thrown: " + e.toString());
}

and output something like...

+7 (999) 111-11-11

which, again, is probably as close as you will get.

Please also remember, formatting phone numbers is not simple as there are no real "standard" rules across all countries ... it's a mess

Sign up to request clarification or add additional context in comments.

4 Comments

maybe related to the country code.... just a guess
@user16320675 Based on the available input and desired output, this works - they weren’t asking about phone numbers 🤷‍♂️
I know it works... and how "they weren’t asking about phone numbers" ?? They wrote "I need to get a phone number" - I believe the downvotes on all answers are because of the country code (+7) of given sample number (again, just my guess... people have reason to not help that country)
@user16320675 Yeah, I probably skimmed over that part - my bad 😓
2

You can use capturing groups and then replace the string as the desired pattern.

Demo:

import java.time.Duration;
import java.util.stream.Stream;

public class Main {
    public static void main(String[] args) {
        String regex = "(\\d)(\\d{3})(\\d{3})(\\d{2})(\\d{2})";
        // Test
        Stream.of(
                "79991111111",
                "12345678901"
        ).forEach(s -> System.out.println(s.replaceAll(regex,"+$1($2)$3-$4-$5")));
    }
}

Output:

+7(999)111-11-11
+1(234)567-89-01

Notes:

  1. There are 5 capturing groups in the regex pattern and each of them has been used with its position as a replaceable parameter in the replacement string.
  2. \d represents a single digit and \d{3} represents three digits in the regex pattern.

Regex Demo

Comments

1

'... I need to get a phone number as a string "79991111111" and convert it to this type of string "+7 (999) 111-11-11". ...'

You can use the StringBuilder#insert method to insert a character into a String value.

StringBuilder string = new StringBuilder("79991111111");
string.insert(0, '+');
string.insert(2, " (");
string.insert(7, ") ");
string.insert(12, '-');
string.insert(15, '-');

Output

+7 (999) 111-11-11

Or, you could use a String#substring for each part of the value.

String string = "79991111111";
String[] strings = {
    string.substring(0, 1),
    string.substring(1, 4),
    string.substring(4, 7),
    string.substring(7, 9),
    string.substring(9)
};
string = "+%s (%s) %s-%s-%s".formatted(strings);

Output

+7 (999) 111-11-11

"... I tried to do it via regex, but i don't know how to change string with using regex"

You can use the String#replaceAll method to capture each group of numbers, and insert values between them.

Since the value will always be the same length, you can use the wildcard character ., and capture syntax ( ).

String string = "79991111111".replaceAll("(.)(...)(...)(..)(..)", "+$1 ($2) $3-$4-$5");

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.