**正则表达式(RegEx)**是一个强大的工具,它帮助我们以灵活、动态和高效的方式匹配模式,并根据结果进行操作。
在本教程中,我们将看看如何使用正则表达式(RegEx)在Java中验证一个电话号码。
用RegEx在Java中验证电话号码
电话号码并不容易验证,而且它们是出了名的灵活。不同的国家有不同的格式,有些国家甚至使用多种格式和国家代码。
为了用正则表达式来验证电话号码,你必须做几个断言,这些断言可以很好地适用于电话号码,除非你想写许多不同的表达式,并通过它们的列表来验证。
这些断言将取决于你的项目、它的本地化和你希望应用的国家--但请记住,对于一个国际项目,你可能不得不放松限制,以免你最终不允许一个有效的电话号码进入系统。
对于标准的美国电话号码验证,我们可以使用冗长的、相当健全的表达式。
^(\+\d{1,2}\s)?\(?\d{3}\)?[\s.-]?\d{3}[\s.-]?\d{4}$
表达式中的4组对应于国家代码、区域号码、用户号码和分机。在这些组之间的表达式是用来处理你所看到的各种不同的格式化。
123-456-7890
(123) 456-7890
etc...
你也可以通过为组(取决于国家)和格式强加一套规则来建立一个不同的表达式,你可能会期望进来。
从技术上讲,你可以简单地检查字符串中是否有10个数字(如果你把国家代码也计算在内,则为12个),它应该能够验证一些电话号码,但这样的简单性需要在前端进行额外的验证,或者在接受的电话号码实际上无效的情况下能够适应。
Pattern simplePattern = Pattern.compile("^\\+\\d{10,12}$");
Pattern robustPattern = Pattern.compile("^(\\+\\d{1,2}\\s)?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}$");
String phoneNumber = "+12 345 678 9012";
Matcher simpleMatcher = simplePattern.matcher(phoneNumber);
Matcher robustMatcher = robustPattern.matcher(phoneNumber);
if (simpleMatcher.matches()) {
System.out.println(String.format("Simple Pattern matched for string: %s", phoneNumber));
}
if(robustMatcher.matches()) {
System.out.println(String.format("Robust Pattern matched for string: %s", phoneNumber));
}
这里的第一个匹配器,首先会对字符串中存在的空白处产生问题,否则会匹配。不过,健壮的模式在这方面没有任何问题。
Robust Pattern matched for string: +12 345 678 9012
这里的健壮匹配器能够匹配多种格式。
Pattern robustPattern = Pattern.compile("^(\\+\\d{1,2}\\s)?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}$");
List<String> phoneNumbers = List.of(
"+12 345 678 9012",
"+123456789012",
"345.678.9012",
"345 678 9012"
);
for (String number : phoneNumbers) {
Matcher matcher = robustPattern.matcher(number);
if(matcher.matches()) {
System.out.println(String.format("Robust Pattern matched for string: %s", number));
}
}
这将导致:
Robust Pattern matched for string: +12 345 678 9012
Robust Pattern matched for string: 345.678.9012
Robust Pattern matched for string: 345 678 9012
结合多个正则表达式
正则表达式往往会变得混乱和冗长。在某种程度上,它们会变得很杂乱,以至于你不能轻易地改变它们或解释它们。
与其拥有一个单一的、通用的、强大的正则表达式来涵盖所有的边缘案例、国家等,不如选择使用几个不同的模式。- 你可以选择使用几个不同的模式,以合理地覆盖进来的电话号码。为了使事情更简单--你可以通过| 操作符将这些表达式连接起来,以检查电话号码是否符合任何模式。
Pattern robustPattern = Pattern
.compile(
// Robust expression from before
"^(\\+\\d{1,2}\\s)?\\(?\\d{3}\\)?[\\s.-]?\\d{3}[\\s.-]?\\d{4}$"
// Area code, within or without parentheses,
// followed by groups of 3-4 numbers with or without hyphens
+ "| ((\\(\\d{3}\\) ?)|(\\d{3}-))?\\d{3}-\\d{4}"
// (+) followed by 10-12 numbers
+ "|^\\+\\d{10,12}"
);
List<String> phoneNumbers = List.of(
"+12 345 678 9012",
"+123456789012",
"345.678.9012",
"345 678 9012"
);
for (String number : phoneNumbers) {
Matcher matcher = robustPattern.matcher(number);
if(matcher.matches()) {
System.out.println(String.format("Pattern matched for string: %s", number));
}
}
这样的结果是:
Pattern matched for string: +12 345 678 9012
Pattern matched for string: +123456789012
Pattern matched for string: 345.678.9012
Pattern matched for string: 345 678 9012
结论
电话号码是很棘手的--这是一个事实。正则表达式是一个非常通用和强大的工具,可以解决验证电话号码的问题,但不得不承认这是一个混乱的过程。
某些国家遵循不同的标准,而有些国家则同时采用和使用多种格式,这使得我们很难编写一个通用的表达式来普遍匹配电话号码。
在这篇短文中,我们通过几个不同的表达式,来看看如何用Java中的正则表达式来匹配电话号码。