有没有办法将 phone 数字标准化为 1-222-444-5555(在北美标准下)?

Is there a way to normalize the phone number to 1-222-444-5555 (under North American standard)?

我想知道是否有办法使用正则表达式模式将 phone 号码标准化为北美标准 (1-222-333-4444)。

该字符串将只包含“-”、空格、“(”、“)”和数字。

谢谢:)

更新:所有可能的输入是:

(123)-456-7890
123-456-7890
1-(123)-456-7890
1-123-456-7890
(123) 456-7890
123 456-7890
1-(123) 456-7890
1-123 456-7890
(123) 456 7890
123 456 7890
1 123 456 7890
1 (123) 456 7890

代码尝试:

public String convertPhone(String newPhone) {
    String regex = "^([\(]{1}[0-9]{3}[\)]{1}[ |\-]{0,1}|^[0-9]{3}[\-| ])?[0-9]{3}(\-| ){1}[0-9]{4}$";
    Pattern pattern = Pattern.compile(regex);
    Matcher matcher = pattern.matcher(newPhone);
    if (matcher.matches()) {
        newPhone = matcher.replaceFirst("1 \(\) -");
        return newPhone;
    } else {
        return "-1";
    }
}

为什么不直接删除非数字字符,然后根据字符串长度重新格式化原始数字。

 String[] phoneNumbers = {
            "(123)-456-7890", "123-456-7890", "1-(123)-456-7890",
            "1-123-456-7890", "(123) 456-7890", "123 456-7890",
            "1-(123) 456-7890", "1-123 456-7890", "(123) 456 7890",
            "123 456 7890", "1 123 456 7890", "1 (123) 456 7890"
      };
      for (String phone : phoneNumbers) {
         String ph = phone.replaceAll("[\(\)\- ]", "");

         if (ph.length() == 11) {
            ph = ph.substring(1);
         }
         String ac = ph.substring(0, 3);
         String exc = ph.substring(3, 6);
         String number = ph.substring(6);
         number = String.format("1 (%s) %s-%s", ac, exc, number);
         System.out.println(number);
      }

也许,类似于

的表达式
(?:1[ -])?[(]?(\d{3})[)]?[ -](\d{3})[ -](\d{4})$

可能涵盖问题中提供的样本,但可能存在边缘情况,例如任何意外的双重 space。

RegEx Demo

测试

import java.util.regex.Matcher;
import java.util.regex.Pattern;


public class RegularExpression{

    public static void main(String[] args){

        final String regex = "(?m)(?:1[ -])?[(]?(\d{3})[)]?[ -](\d{3})[ -](\d{4})$";
        final String string = "(123)-456-7890\n"
             + "123-456-7890\n"
             + "1-(123)-456-7890\n"
             + "1-123-456-7890\n"
             + "(123) 456-7890\n"
             + "123 456-7890\n"
             + "1-(123) 456-7890\n"
             + "1-123 456-7890\n"
             + "(123) 456 7890\n"
             + "123 456 7890\n"
             + "1 123 456 7890\n"
             + "1 (123) 456 7890";
        final String subst = "1---";

        final Pattern pattern = Pattern.compile(regex);
        final Matcher matcher = pattern.matcher(string);

        final String result = matcher.replaceAll(subst);

        System.out.println(result);


    }
}

输出

1-123-456-7890
1-123-456-7890
1-123-456-7890
1-123-456-7890
1-123-456-7890
1-123-456-7890
1-123-456-7890
1-123-456-7890
1-123-456-7890
1-123-456-7890
1-123-456-7890
1-123-456-7890

如果你想simplify/update/explore这个表达式,在regex101.com. You can watch the matching steps or modify them in this debugger link, if you'd be interested. The debugger demonstrates that how a RegEx engine的右上面板已经解释过可能会逐步消耗一些示例输入字符串并执行匹配过程。


正则表达式电路

jex.im 可视化正则表达式:

我认为这可以通过简单地查找数字而忽略国家代码和数字组之间的所有内容来完成。此正则表达式可以处理所有存在额外空格或任何非数字字符且数字之间没有空格的示例和情况。

1?\D*(\d{3})\D*(\d{3})\D*(\d{4})\b

然后你可以用这个模式替换数字。

1---