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

35

我一直将电话号码存储为long类型,现在我想在将电话号码作为字符串打印时添加连字符。

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

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

理想情况下,我希望区号也能加上括号。
new DecimalFormat("(###)-###-####");

这该怎么做才是正确的方式?

11
将电话号码以数字类型(如long)存储并不是一个好主意。电话号码实际上是一种标识,而不是你想进行计算的数字。如果一个电话号码以0开头,那么你无法将其存储在数字类型中。 - Jesper
17个回答

53

你可以使用String.replaceFirst方法并使用正则表达式的方式进行替换,例如:

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

我使用这个工具生成符合特定格式的随机ID号码。谢谢。 - crownjewel82
1
正则表达式没问题,但在紧密循环中使用会非常慢。 - trilogy

26
为了得到你想要的输出:
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

如果要存储电话号码,则应该考虑使用数据类型而不是数字


20

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

您可以像这样操作:

import javax.swing.text.MaskFormatter;

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

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

1
如果您将其与DecimalFormat结合使用,那么这非常容易。但是,MaskFormatter的checked ParseException确实很烦人。 - Roland Schneider
运行良好。我将其制作为一个实用方法。 - Marc Bouvier

9

如果你真的需要正确的方法,那么你可以使用谷歌最近开源的libphonenumber


3
我认为另一个库是不必要的。使用各种不同的Java格式化API肯定有一种简单的方法可以做到这一点。我只是不知道该用哪一个。 - styfle
6
仅仅格式不是你的问题,将电话号码存储在long中才是。 - Joachim Sauer

9
您也可以使用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


6
最糟糕的解决方案是:
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);

2
我怀疑那不是最糟糕的 - 开发人员可以非常有创意 [:-) ] - user85421

6
这就是我最终的做法:
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个字符长的电话号码。我只是想以一些格式打印它。
感谢您的回复。

4
你可以实现自己的方法来为你执行此操作,我建议你使用以下内容: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

2

您可以使用我的工具类对任何包含非数字字符的字符串进行格式化,以符合您的要求。

使用方法非常简单

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 和电话号码的长度。如果输入长度大于指定的长度,则字符串将被修剪。

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


2
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);
}

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接