如何在 Java 中将电话号码格式化为字符串?

发布于 2024-10-19 07:28:17 字数 424 浏览 3 评论 0原文

我一直将电话号码存储为很长的长度,我想在将电话号码打印为字符串时简单地添加连字符。

我尝试使用 DecimalFormat 但它不喜欢连字符。可能是因为它用于格式化十进制数字而不是长整数。

long phoneFmt = 123456789L;
DecimalFormat phoneFmt = new DecimalFormat("###-###-####");
System.out.println(phoneFmt.format(phoneNum)); //doesn't work as I had hoped

理想情况下,我也想在区号上加上括号。

new DecimalFormat("(###)-###-####");

这样做的正确方法是什么?

I have been storing phone numbers as longs and I would like to simply add hyphens when printing the phone number as a string.

I tried using DecimalFormat but that doesn't like the hyphen. Probably because it is meant for formatting decimal numbers and not longs.

long phoneFmt = 123456789L;
DecimalFormat phoneFmt = new DecimalFormat("###-###-####");
System.out.println(phoneFmt.format(phoneNum)); //doesn't work as I had hoped

Ideally, I would like to have parenthesis on the area code too.

new DecimalFormat("(###)-###-####");

What is the correct way to do this?

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(18

栖迟 2024-10-26 07:28:17

您可以使用 String.replaceFirst 使用正则表达式方法,例如

    long phoneNum = 123456789L;
    System.out.println(String.valueOf(phoneNum).replaceFirst("(\\d{3})(\\d{3})(\\d+)", "($1)-$2-$3"));

You can use String.replaceFirst with regex method like

    long phoneNum = 123456789L;
    System.out.println(String.valueOf(phoneNum).replaceFirst("(\\d{3})(\\d{3})(\\d+)", "($1)-$2-$3"));
天气好吗我好吗 2024-10-26 07:28:17

要获得所需的输出:

long phoneFmt = 123456789L;
//get a 12 digits String, filling with left '0' (on the prefix)   
DecimalFormat phoneDecimalFmt = new DecimalFormat("0000000000");
String phoneRawString= phoneDecimalFmt.format(phoneFmt);

java.text.MessageFormat phoneMsgFmt=new java.text.MessageFormat("({0})-{1}-{2}");
    //suposing a grouping of 3-3-4
String[] phoneNumArr={phoneRawString.substring(0, 3),
          phoneRawString.substring(3,6),
          phoneRawString.substring(6)};

System.out.println(phoneMsgFmt.format(phoneNumArr));

控制台上的结果如下所示:

(012)-345-6789

对于存储电话号码,您应该考虑 使用数字以外的数据类型

To get your desired output:

long phoneFmt = 123456789L;
//get a 12 digits String, filling with left '0' (on the prefix)   
DecimalFormat phoneDecimalFmt = new DecimalFormat("0000000000");
String phoneRawString= phoneDecimalFmt.format(phoneFmt);

java.text.MessageFormat phoneMsgFmt=new java.text.MessageFormat("({0})-{1}-{2}");
    //suposing a grouping of 3-3-4
String[] phoneNumArr={phoneRawString.substring(0, 3),
          phoneRawString.substring(3,6),
          phoneRawString.substring(6)};

System.out.println(phoneMsgFmt.format(phoneNumArr));

The result at the Console looks like this:

(012)-345-6789

For storing phone numbers, you should consider using a data type other than numbers.

简单爱 2024-10-26 07:28:17

最简单的方法是使用 javax 中内置的 MaskFormatter .swing.文本库

你可以这样做:

import javax.swing.text.MaskFormatter;

String phoneMask= "###-###-####";
String phoneNumber= "123423452345";

MaskFormatter maskFormatter= new MaskFormatter(phoneMask);
maskFormatter.setValueContainsLiteralCharacters(false);
maskFormatter.valueToString(phoneNumber) ;

The easiest way to do this is by using the built in MaskFormatter in the javax.swing.text library.

You can do something like this :

import javax.swing.text.MaskFormatter;

String phoneMask= "###-###-####";
String phoneNumber= "123423452345";

MaskFormatter maskFormatter= new MaskFormatter(phoneMask);
maskFormatter.setValueContainsLiteralCharacters(false);
maskFormatter.valueToString(phoneNumber) ;
画▽骨i 2024-10-26 07:28:17

如果您确实需要正确的方法,那么您可以使用 Google 最近开源的 libphonenumber

If you really need the right way then you can use Google's recently open sourced libphonenumber

(り薆情海 2024-10-26 07:28:17

您还可以使用 https://github.com/googlei18n/libphonenumber。这是一个示例:

import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;

String s = "18005551234";
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
Phonenumber.PhoneNumber phoneNumber = phoneUtil.parse(s, Locale.US.getCountry());
String formatted = phoneUtil.format(phoneNumber, PhoneNumberUtil.PhoneNumberFormat.NATIONAL);

您可以在此处获取类路径上的库:http://mvnrepository。 com/artifact/com.googlecode.libphonenumber/libphonenumber

You could also use https://github.com/googlei18n/libphonenumber. Here is an example:

import com.google.i18n.phonenumbers.NumberParseException;
import com.google.i18n.phonenumbers.PhoneNumberUtil;
import com.google.i18n.phonenumbers.Phonenumber;

String s = "18005551234";
PhoneNumberUtil phoneUtil = PhoneNumberUtil.getInstance();
Phonenumber.PhoneNumber phoneNumber = phoneUtil.parse(s, Locale.US.getCountry());
String formatted = phoneUtil.format(phoneNumber, PhoneNumberUtil.PhoneNumberFormat.NATIONAL);

Here you can get the library on your classpath: http://mvnrepository.com/artifact/com.googlecode.libphonenumber/libphonenumber

如痴如狂 2024-10-26 07:28:17

最糟糕的解决方案可能是:

StringBuilder sb = new StringBuilder();
long tmp = phoneFmt;
sb.append("(");
sb.append(tmp / 10000000);
tmp = tmp % 10000000;
sb.append(")-");
sb.apppend(tmp / 10000);
tmp = tmp % 10000000;
sb.append("-");
sb.append(tmp);

The worst possible solution would be:

StringBuilder sb = new StringBuilder();
long tmp = phoneFmt;
sb.append("(");
sb.append(tmp / 10000000);
tmp = tmp % 10000000;
sb.append(")-");
sb.apppend(tmp / 10000);
tmp = tmp % 10000000;
sb.append("-");
sb.append(tmp);
悲歌长辞 2024-10-26 07:28:17

这就是我最终这样做的方式:

private String printPhone(Long phoneNum) {
    StringBuilder sb = new StringBuilder(15);
    StringBuilder temp = new StringBuilder(phoneNum.toString());

    while (temp.length() < 10)
        temp.insert(0, "0");

    char[] chars = temp.toString().toCharArray();

    sb.append("(");
    for (int i = 0; i < chars.length; i++) {
        if (i == 3)
            sb.append(") ");
        else if (i == 6)
            sb.append("-");
        sb.append(chars[i]);
    }

    return sb.toString();
}

我知道这不支持国际号码,但我没有编写“真正的”应用程序,所以我不担心这一点。我只接受 10 个字符长的电话号码。我只是想用一些格式打印它。

感谢您的回复。

This is how I ended up doing it:

private String printPhone(Long phoneNum) {
    StringBuilder sb = new StringBuilder(15);
    StringBuilder temp = new StringBuilder(phoneNum.toString());

    while (temp.length() < 10)
        temp.insert(0, "0");

    char[] chars = temp.toString().toCharArray();

    sb.append("(");
    for (int i = 0; i < chars.length; i++) {
        if (i == 3)
            sb.append(") ");
        else if (i == 6)
            sb.append("-");
        sb.append(chars[i]);
    }

    return sb.toString();
}

I understand that this does not support international numbers, but I'm not writing a "real" application so I'm not concerned about that. I only accept a 10 character long as a phone number. I just wanted to print it with some formatting.

Thanks for the responses.

往事随风而去 2024-10-26 07:28:17

您可以实现自己的方法来为您做到这一点,我建议您使用类似的方法。使用DecimalFormatMessageFormat。使用此方法,您几乎可以使用任何您想要的内容(String、Integer、Float、Double),并且输出将始终正确。

import java.text.DecimalFormat;
import java.text.MessageFormat;

/**
 * Created by Yamil Garcia Hernandez on 25/4/16.
 */

public class test {
    // Constants
    public static final DecimalFormat phoneFormatD = new DecimalFormat("0000000000");
    public static final MessageFormat phoneFormatM = new MessageFormat("({0}) {1}-{2}");

    // Example Method on a Main Class
    public static void main(String... args) {
        try {
            System.out.println(formatPhoneNumber("8091231234"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            System.out.println(formatPhoneNumber("18091231234"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            System.out.println(formatPhoneNumber("451231234"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            System.out.println(formatPhoneNumber("11231234"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            System.out.println(formatPhoneNumber("1231234"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            System.out.println(formatPhoneNumber("231234"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            System.out.println(formatPhoneNumber(""));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            System.out.println(formatPhoneNumber(0));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            System.out.println(formatPhoneNumber(8091231234f));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // Magic
    public static String formatPhoneNumber(Object phone) throws Exception {

        double p = 0;

        if (phone instanceof String)
            p = Double.valueOf((String) phone);

        if (phone instanceof Integer)
            p = (Integer) phone;

        if (phone instanceof Float)
            p = (Float) phone;

        if (phone instanceof Double)
            p = (Double) phone;

        if (p == 0 || String.valueOf(p) == "" || String.valueOf(p).length() < 7)
            throw new Exception("Paramenter is no valid");

        String fot = phoneFormatD.format(p);

        String extra = fot.length() > 10 ? fot.substring(0, fot.length() - 10) : "";
        fot = fot.length() > 10 ? fot.substring(fot.length() - 10, fot.length()) : fot;

        String[] arr = {
                (fot.charAt(0) != '0') ? fot.substring(0, 3) : (fot.charAt(1) != '0') ? fot.substring(1, 3) : fot.substring(2, 3),
                fot.substring(3, 6),
                fot.substring(6)
        };
        String r = phoneFormatM.format(arr);
        r = (r.contains("(0)")) ? r.replace("(0) ", "") : r;
        r = (extra != "") ? ("+" + extra + " " + r) : r;
        return (r);
    }
}

结果将是

(809) 123-1234
+1 (809) 123-1234
(45) 123-1234
(1) 123-1234
123-1234
023-1234
java.lang.NumberFormatException: empty String
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
    at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
    at java.lang.Double.parseDouble(Double.java:538)
    at java.lang.Double.valueOf(Double.java:502)
    at test.formatPhoneNumber(test.java:66)
    at test.main(test.java:45)
java.lang.Exception: Paramenter is no valid
    at test.formatPhoneNumber(test.java:78)
    at test.main(test.java:50)
(809) 123-1232

You can implement your own method to do that for you, I recommend you to use something such as this. Using DecimalFormat and MessageFormat. With this method you can use pretty much whatever you want (String,Integer,Float,Double) and the output will be always right.

import java.text.DecimalFormat;
import java.text.MessageFormat;

/**
 * Created by Yamil Garcia Hernandez on 25/4/16.
 */

public class test {
    // Constants
    public static final DecimalFormat phoneFormatD = new DecimalFormat("0000000000");
    public static final MessageFormat phoneFormatM = new MessageFormat("({0}) {1}-{2}");

    // Example Method on a Main Class
    public static void main(String... args) {
        try {
            System.out.println(formatPhoneNumber("8091231234"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            System.out.println(formatPhoneNumber("18091231234"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            System.out.println(formatPhoneNumber("451231234"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            System.out.println(formatPhoneNumber("11231234"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            System.out.println(formatPhoneNumber("1231234"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            System.out.println(formatPhoneNumber("231234"));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            System.out.println(formatPhoneNumber(""));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            System.out.println(formatPhoneNumber(0));
        } catch (Exception e) {
            e.printStackTrace();
        }
        try {
            System.out.println(formatPhoneNumber(8091231234f));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }
    // Magic
    public static String formatPhoneNumber(Object phone) throws Exception {

        double p = 0;

        if (phone instanceof String)
            p = Double.valueOf((String) phone);

        if (phone instanceof Integer)
            p = (Integer) phone;

        if (phone instanceof Float)
            p = (Float) phone;

        if (phone instanceof Double)
            p = (Double) phone;

        if (p == 0 || String.valueOf(p) == "" || String.valueOf(p).length() < 7)
            throw new Exception("Paramenter is no valid");

        String fot = phoneFormatD.format(p);

        String extra = fot.length() > 10 ? fot.substring(0, fot.length() - 10) : "";
        fot = fot.length() > 10 ? fot.substring(fot.length() - 10, fot.length()) : fot;

        String[] arr = {
                (fot.charAt(0) != '0') ? fot.substring(0, 3) : (fot.charAt(1) != '0') ? fot.substring(1, 3) : fot.substring(2, 3),
                fot.substring(3, 6),
                fot.substring(6)
        };
        String r = phoneFormatM.format(arr);
        r = (r.contains("(0)")) ? r.replace("(0) ", "") : r;
        r = (extra != "") ? ("+" + extra + " " + r) : r;
        return (r);
    }
}

Result will be

(809) 123-1234
+1 (809) 123-1234
(45) 123-1234
(1) 123-1234
123-1234
023-1234
java.lang.NumberFormatException: empty String
    at sun.misc.FloatingDecimal.readJavaFormatString(FloatingDecimal.java:1842)
    at sun.misc.FloatingDecimal.parseDouble(FloatingDecimal.java:110)
    at java.lang.Double.parseDouble(Double.java:538)
    at java.lang.Double.valueOf(Double.java:502)
    at test.formatPhoneNumber(test.java:66)
    at test.main(test.java:45)
java.lang.Exception: Paramenter is no valid
    at test.formatPhoneNumber(test.java:78)
    at test.main(test.java:50)
(809) 123-1232
伏妖词 2024-10-26 07:28:17

DecimalFormat 不允许对数字内的任意文本进行格式化,就像前缀或后缀一样。所以它无法帮助你。

在我看来,将电话号码存储为数值是完全错误的。如果我想存储国际号码怎么办?许多国家/地区使用 + 表示国家/地区代码(例如,+1 表示美国/加拿大),其他国家/地区则使用 00(例如 001< /代码>)。

这两者都不能真正用数字数据类型表示(“这个数字是 1555123 还是 001555123?”)

DecimalFormat doesn't allow arbitrary text within the number to be formatted, just as a prefix or a suffix. So it won't be able to help you there.

In my opinion, storing a phone number as a numeric value is wrong, entirely. What if I want to store an international number? Many countries use + to indicate a country code (e.g. +1 for USA/Canda), others use 00 (e.g. 001).

Both of those can't really be represented in a numeric data type ("Is that number 1555123 or 001555123?")

拥抱我好吗 2024-10-26 07:28:17

您也可以使用子字符串和连接来轻松格式化。

telephoneNumber = "("+telephoneNumber.substring(0, 3)+")-"+telephoneNumber.substring(3, 6)+"-"+telephoneNumber.substring(6, 10);

但需要注意的一件事是,您必须检查电话号码字段的长度,以确保格式安全。

You could use the substring and concatenation for easy formatting too.

telephoneNumber = "("+telephoneNumber.substring(0, 3)+")-"+telephoneNumber.substring(3, 6)+"-"+telephoneNumber.substring(6, 10);

But one thing to note is that you must check for the lenght of the telephone number field just to make sure that your formatting is safe.

山色无中 2024-10-26 07:28:17

您可以将任何包含非数字字符的字符串格式化为您想要的格式,使用我的 util 类来格式化

用法非常简单的

public static void main(String[] args){
    String num = "ab12345*&67890";

    System.out.println(PhoneNumberUtil.formateToPhoneNumber(num,"(XXX)-XXX-XXXX",10));
}

输出:(123)-456-7890

您可以指定任何格式,例如 XXX-XXX-XXXX 和手机长度number ,如果输入长度大于指定长度,则字符串将被修剪。

从这里获取我的课程: https://github.com/gajeralalji/PhoneNumberUtil/blob /master/PhoneNumberUtil.java

U can format any string containing non numeric characters also to your desired format use my util class to format

usage is very simple

public static void main(String[] args){
    String num = "ab12345*&67890";

    System.out.println(PhoneNumberUtil.formateToPhoneNumber(num,"(XXX)-XXX-XXXX",10));
}

output: (123)-456-7890

u can specify any foramt such as XXX-XXX-XXXX and length of the phone number , if input length is greater than specified length then string will be trimmed.

Get my class from here: https://github.com/gajeralalji/PhoneNumberUtil/blob/master/PhoneNumberUtil.java

深海蓝天 2024-10-26 07:28:17
Pattern phoneNumber = Pattern.compile("(\\d{3})(\\d{3})(\\d{4})");
// ...
Matcher matcher = phoneNumber(numberAsLineOf10Symbols);
if (matcher.matches) {
    return "(" + matcher.group(1) + ")-" +matcher.group(2) + "-" + matcher.group(3);
}
Pattern phoneNumber = Pattern.compile("(\\d{3})(\\d{3})(\\d{4})");
// ...
Matcher matcher = phoneNumber(numberAsLineOf10Symbols);
if (matcher.matches) {
    return "(" + matcher.group(1) + ")-" +matcher.group(2) + "-" + matcher.group(3);
}
只为守护你 2024-10-26 07:28:17

我认为您需要使用 MessageFormat 而不是 DecimalFormat。这样应该更灵活。

I'd have thought you need to use a MessageFormat rather than DecimalFormat. That should be more flexible.

为你鎻心 2024-10-26 07:28:17

String formatterPhone = String.format("%s-%s-%s",phoneNumber.substring(0, 3),phoneNumber.substring(3, 6),phoneNumber.substring(6, 10));

String formatterPhone = String.format("%s-%s-%s", phoneNumber.substring(0, 3), phoneNumber.substring(3, 6), phoneNumber.substring(6, 10));

场罚期间 2024-10-26 07:28:17

使用 StringBuilder 来提高性能。

long number = 12345678L;

System.out.println(getPhoneFormat(String.valueOf(number)));

public static String getPhoneFormat(String number)
{
    if (number == null || number.isEmpty() || number.length() < 6 || number.length() > 15)
    {
        return number;
    }

    return new StringBuilder("(").append(number.substring(0, 3))
            .append(") ").append(number.substring(3, 6))
            .append("-").append(number.substring(6))
            .toString();

}

Using StringBuilder for performance.

long number = 12345678L;

System.out.println(getPhoneFormat(String.valueOf(number)));

public static String getPhoneFormat(String number)
{
    if (number == null || number.isEmpty() || number.length() < 6 || number.length() > 15)
    {
        return number;
    }

    return new StringBuilder("(").append(number.substring(0, 3))
            .append(") ").append(number.substring(3, 6))
            .append("-").append(number.substring(6))
            .toString();

}
征﹌骨岁月お 2024-10-26 07:28:17

Kotlin

val number = 088899998888

val phone = number.phoneFormatter()

fun String.phoneFormatter(): String { return this.replace("\\B(?=(\\d{4})+(?!\\d))".toRegex(), "-") }

结果将是 0888-9999-8888

Kotlin

val number = 088899998888

val phone = number.phoneFormatter()

fun String.phoneFormatter(): String { return this.replace("\\B(?=(\\d{4})+(?!\\d))".toRegex(), "-") }

The result will be 0888-9999-8888

烛影斜 2024-10-26 07:28:17

我用了这个

String columValue = "1234567890

String number = columValue.replaceFirst("(\d{3})(\d{3})(\d+)", "($1) $2-$3");

I used this one

String columValue = "1234567890

String number = columValue.replaceFirst("(\d{3})(\d{3})(\d+)", "($1) $2-$3");

风尘浪孓 2024-10-26 07:28:17

我编写了以下代码

import java.io.IOException;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

/**
 * Produces a string suitable for representing phone numbers by formatting them according with the format string
 */
@Slf4j
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder(builderMethodName = "builderInternal")
public class PhoneNumberFormatter {

    /** Format string used to represent phone numbers */
    @Getter @Builder.Default private String formatString = "(###)###-";
    
    /** String used to represent null phone numbers */
    @Getter @Builder.Default private String nullString = "---";
    
    /** Pattern used for substitutions of phone numbers. 
     * Pounds (#) are replaced by phone digits unless they are escaped (\#) */
    private static final Pattern PATTERN = Pattern.compile("\\\\#|#");
   
    /** Returns a new formatter with default parameters */
    public static PhoneNumberFormatter of() {
        return builder().build();
    }
    
    /** Returns a new formatter with the format string */
    public static PhoneNumberFormatter of(String formatString) {
        return builder(formatString).build();
    }
    
    /** Create a builder object. Notice that lombok does most of the work in builderInternal
     * but we want to pass the format string to the builder method directly */
    public static PhoneNumberFormatterBuilder builder(String formatString) {
        Objects.requireNonNull(formatString, "formatString");
        return builder().formatString(formatString);
    }
    
    /** Create a new builder with default parameters. Notice that builderInternal is created by lombok */
    public static PhoneNumberFormatterBuilder builder() {
        return builderInternal();
    }
    
    /** Return a formatted string corresponding to the given user */
    public String format(String phoneNumber) {
        StringBuilder buf = new StringBuilder(32);
        formatTo(phoneNumber, buf);
        return buf.toString();
    }
    
    /** Append a formatted string corresponding to the given user to the given appendable */
    public void formatTo(String phoneNumber, Appendable appendable) {
        Objects.requireNonNull(appendable, "appendable");

        if (appendable instanceof StringBuilder) {
            doFormat(phoneNumber, (StringBuilder) appendable);
        } else {
            // buffer output to avoid writing to appendable in case of error
            StringBuilder buf = new StringBuilder(32);
            doFormat(phoneNumber, buf);
            try {
                appendable.append(buf);
            } catch (IOException e) {
                log.warn("Could not append phone number {} to {appendable}", phoneNumber, e);
            }
        }
    }
    
    /** Performs regex search and replacement of digits */
    private void doFormat(String phoneNumber, StringBuilder result) {
        if (phoneNumber == null) {
            result.append(nullString);
            return;
        }
        Matcher matcher = PATTERN.matcher(formatString);
        int digitIndex = 0;
        while (matcher.find()) {
            if (matcher.group().equals("\\#")) {
                matcher.appendReplacement(result, "#");
            } else if (digitIndex < phoneNumber.length()) {
                matcher.appendReplacement(result, String.valueOf(phoneNumber.charAt(digitIndex)));
                digitIndex++;
            } else {
                break; // Stop if there are no more digits in the phone number
            }
        }
        matcher.appendTail(result);
        result.append(phoneNumber.substring(digitIndex));
    }
    
}

这是一些示例用法的测试代码:

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;

public class PhoneNumberFormatterTest {

  @Test
  public void nullArgsTest() {

    assertThrows(NullPointerException.class, () -> PhoneNumberFormatter.of(null),
    "Expected using null as a format string to fail, but it didn't");
    
    PhoneNumberFormatter f = PhoneNumberFormatter.of();
    assertEquals(f.getNullString(), f.format(null));
    
    f = PhoneNumberFormatter.builder().nullString("null phone").build();
    assertEquals("null phone", f.format(null));
    
    assertThrows(NullPointerException.class, () -> PhoneNumberFormatter.of().formatTo("12345", null),
    "Expected appending to a null appender to fail, but it didn't");
    
  }

  @Test
  public void validTests() {
      PhoneNumberFormatter f = PhoneNumberFormatter.of();
      String p = "1234567890";
      assertEquals("(123)456-7890", f.format(p));
      
      StringBuffer s = new StringBuffer("Hello this is a phone number: ");
      f.formatTo(p, s);
      assertEquals("Hello this is a phone number: (123)456-7890", s.toString());
      
      f = PhoneNumberFormatter.of("(###)###-####");
      assertEquals("(123)456-7890", f.format(p));
      assertEquals("(555)456-7890", f.format("5554567890"));      
      
      f = PhoneNumberFormatter.of("(###) ###-####");
      assertEquals("(123) 456-7890", f.format(p));
      
      f = PhoneNumberFormatter.of("+1(###)###-####");
      assertEquals("+1(123)456-7890", f.format(p));
      
      f = PhoneNumberFormatter.of("\\#(###)\\####-");
      assertEquals("#(123)#456-7890", f.format(p));
      
      f = PhoneNumberFormatter.of("\\\\#(###)\\####-");
      assertEquals("\\#(123)#456-7890", f.format(p));
      
      f = PhoneNumberFormatter.of("(###)###-####-####");
      assertEquals("(123)456-7890-####", f.format(p));
      
      
  }
  
}

I wrote the following code

import java.io.IOException;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import lombok.AccessLevel;
import lombok.AllArgsConstructor;
import lombok.Builder;
import lombok.Getter;
import lombok.extern.slf4j.Slf4j;

/**
 * Produces a string suitable for representing phone numbers by formatting them according with the format string
 */
@Slf4j
@AllArgsConstructor(access = AccessLevel.PRIVATE)
@Builder(builderMethodName = "builderInternal")
public class PhoneNumberFormatter {

    /** Format string used to represent phone numbers */
    @Getter @Builder.Default private String formatString = "(###)###-";
    
    /** String used to represent null phone numbers */
    @Getter @Builder.Default private String nullString = "---";
    
    /** Pattern used for substitutions of phone numbers. 
     * Pounds (#) are replaced by phone digits unless they are escaped (\#) */
    private static final Pattern PATTERN = Pattern.compile("\\\\#|#");
   
    /** Returns a new formatter with default parameters */
    public static PhoneNumberFormatter of() {
        return builder().build();
    }
    
    /** Returns a new formatter with the format string */
    public static PhoneNumberFormatter of(String formatString) {
        return builder(formatString).build();
    }
    
    /** Create a builder object. Notice that lombok does most of the work in builderInternal
     * but we want to pass the format string to the builder method directly */
    public static PhoneNumberFormatterBuilder builder(String formatString) {
        Objects.requireNonNull(formatString, "formatString");
        return builder().formatString(formatString);
    }
    
    /** Create a new builder with default parameters. Notice that builderInternal is created by lombok */
    public static PhoneNumberFormatterBuilder builder() {
        return builderInternal();
    }
    
    /** Return a formatted string corresponding to the given user */
    public String format(String phoneNumber) {
        StringBuilder buf = new StringBuilder(32);
        formatTo(phoneNumber, buf);
        return buf.toString();
    }
    
    /** Append a formatted string corresponding to the given user to the given appendable */
    public void formatTo(String phoneNumber, Appendable appendable) {
        Objects.requireNonNull(appendable, "appendable");

        if (appendable instanceof StringBuilder) {
            doFormat(phoneNumber, (StringBuilder) appendable);
        } else {
            // buffer output to avoid writing to appendable in case of error
            StringBuilder buf = new StringBuilder(32);
            doFormat(phoneNumber, buf);
            try {
                appendable.append(buf);
            } catch (IOException e) {
                log.warn("Could not append phone number {} to {appendable}", phoneNumber, e);
            }
        }
    }
    
    /** Performs regex search and replacement of digits */
    private void doFormat(String phoneNumber, StringBuilder result) {
        if (phoneNumber == null) {
            result.append(nullString);
            return;
        }
        Matcher matcher = PATTERN.matcher(formatString);
        int digitIndex = 0;
        while (matcher.find()) {
            if (matcher.group().equals("\\#")) {
                matcher.appendReplacement(result, "#");
            } else if (digitIndex < phoneNumber.length()) {
                matcher.appendReplacement(result, String.valueOf(phoneNumber.charAt(digitIndex)));
                digitIndex++;
            } else {
                break; // Stop if there are no more digits in the phone number
            }
        }
        matcher.appendTail(result);
        result.append(phoneNumber.substring(digitIndex));
    }
    
}

This is some test code that exemplifies the usage:

import static org.junit.jupiter.api.Assertions.assertEquals;
import static org.junit.jupiter.api.Assertions.assertThrows;
import org.junit.jupiter.api.Test;

public class PhoneNumberFormatterTest {

  @Test
  public void nullArgsTest() {

    assertThrows(NullPointerException.class, () -> PhoneNumberFormatter.of(null),
    "Expected using null as a format string to fail, but it didn't");
    
    PhoneNumberFormatter f = PhoneNumberFormatter.of();
    assertEquals(f.getNullString(), f.format(null));
    
    f = PhoneNumberFormatter.builder().nullString("null phone").build();
    assertEquals("null phone", f.format(null));
    
    assertThrows(NullPointerException.class, () -> PhoneNumberFormatter.of().formatTo("12345", null),
    "Expected appending to a null appender to fail, but it didn't");
    
  }

  @Test
  public void validTests() {
      PhoneNumberFormatter f = PhoneNumberFormatter.of();
      String p = "1234567890";
      assertEquals("(123)456-7890", f.format(p));
      
      StringBuffer s = new StringBuffer("Hello this is a phone number: ");
      f.formatTo(p, s);
      assertEquals("Hello this is a phone number: (123)456-7890", s.toString());
      
      f = PhoneNumberFormatter.of("(###)###-####");
      assertEquals("(123)456-7890", f.format(p));
      assertEquals("(555)456-7890", f.format("5554567890"));      
      
      f = PhoneNumberFormatter.of("(###) ###-####");
      assertEquals("(123) 456-7890", f.format(p));
      
      f = PhoneNumberFormatter.of("+1(###)###-####");
      assertEquals("+1(123)456-7890", f.format(p));
      
      f = PhoneNumberFormatter.of("\\#(###)\\####-");
      assertEquals("#(123)#456-7890", f.format(p));
      
      f = PhoneNumberFormatter.of("\\\\#(###)\\####-");
      assertEquals("\\#(123)#456-7890", f.format(p));
      
      f = PhoneNumberFormatter.of("(###)###-####-####");
      assertEquals("(123)456-7890-####", f.format(p));
      
      
  }
  
}
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文