我正在尝试编写一个全面的正则表达式来验证电话号码。理想情况下,它将处理国际格式,但必须处理美国格式,包括以下格式:
1-234-567-8901
1-234-567-8901 x1234
1-234-567-8901 ext1234
1 (234) 567-8901
1.234.567.8901
1/234/567/8901
12345678901
我会回答我的当前尝试,但我希望有人能提供更好和/或更优雅的解决方案。
我正在尝试编写一个全面的正则表达式来验证电话号码。理想情况下,它将处理国际格式,但必须处理美国格式,包括以下格式:
1-234-567-8901
1-234-567-8901 x1234
1-234-567-8901 ext1234
1 (234) 567-8901
1.234.567.8901
1/234/567/8901
12345678901
我会回答我的当前尝试,但我希望有人能提供更好和/或更优雅的解决方案。
我倾向于认同只保留数字并接受现有数据的做法。也许可以确保至少有几个数字存在,尽管这样会阻止像“ASK-JAKE”这样的字母电话号码。
一些简单的Perl表达式可能是:
@f = /(\d+)/g;
tr/0-9//dc;
使用第一个方法将数字组合在一起,这可能会提供格式化提示。使用第二个方法可以轻松地丢弃所有非数字字符。
如果需要暂停然后输入更多按键,或者像555-1212(等待哔声)123这样的情况是否令人担忧?
1[\s./-]?\(?[\d]+\)?[\s./-]?[\d]+[-/.]?[\d]+\s?[\d]+
当在Python中使用时:
import re
phonelist ="1-234-567-8901,1-234-567-8901 1234,1-234-567-8901 1234,1 (234) 567-8901,1.234.567.8901,1/234/567/8901,12345678901"
phonenumber = '\n'.join([phone for phone in re.findall(r'1[\s./-]?\(?[\d]+\)?[\s./-]?[\d]+[-/.]?[\d]+\s?[\d]+' ,phonelist)])
print(phonenumber)
输出:
1-234-567-8901
1-234-567-8901 1234
1-234-567-8901 1234
1 (234) 567-8901
1.234.567.8901
1/234/567/8901
12345678901
使用简单的正则表达式处理各种国际电话号码几乎是不可能的。
最好使用像numverify.com这样的服务,他们提供免费的JSON API用于国际电话号码验证,每次请求还会得到有关国家、位置、运营商和线路类型的一些有用详细信息。
BAD_AREA_CODES = open('badareacodes.txt', 'r').read().split('\n')
def is_valid_phone(phone_number, country_code='US'):
"""for now, only US codes are handled"""
if country_code:
country_code = country_code.upper()
#drop everything except 0-9 and 'x'
phone_number = filter(lambda n: n.isdigit() or n == 'x', phone_number)
ext = None
check_ext = phone_number.split('x')
if len(check_ext) > 1:
#there's an extension. Check for errors.
if len(check_ext) > 2:
return False
phone_number, ext = check_ext
#we only accept 10 digit phone numbers.
if len(phone_number) == 11 and phone_number[0] == '1':
#international code
phone_number = phone_number[1:]
if len(phone_number) != 10:
return False
#area_code: XXXxxxxxxx
#head: xxxXXXxxxx
#tail: xxxxxxXXXX
area_code = phone_number[ :3]
head = phone_number[3:6]
tail = phone_number[6: ]
if area_code in BAD_AREA_CODES:
return False
if head[0] == '1':
return False
if head[1:] == '11':
return False
#any other ideas?
return True
土耳其的工作示例,只需更改
d{9}
function validateMobile($phone)
{
$pattern = "/^(05)\d{9}$/";
if (!preg_match($pattern, $phone))
{
return false;
}
return true;
}
$phone = "0532486061";
if(!validateMobile($phone))
{
echo 'Incorrect Mobile Number!';
}
$phone = "05324860614";
if(validateMobile($phone))
{
echo 'Correct Mobile Number!';
}
尝试这个(它是用于印度手机号码验证的):
if (!phoneNumber.matches("^[6-9]\\d{9}$")) {
return false;
} else {
return true;
}
matches
的输出呢? - nice_dev虽然它不是正则表达式,但你可以使用 Python 库 DataPrep 中的函数 validate_phone()
来验证美国电话号码。使用 pip install dataprep
命令安装它。
>>> from dataprep.clean import validate_phone
>>> df = pd.DataFrame({'phone': ['1-234-567-8901', '1-234-567-8901 x1234',
'1-234-567-8901 ext1234', '1 (234) 567-8901', '1.234.567.8901',
'1/234/567/8901', 12345678901, '12345678', '123-456-78987']})
>>> validate_phone(df['phone'])
0 True
1 True
2 True
3 True
4 True
5 True
6 True
7 False
8 False
Name: phone, dtype: bool
注意:该函数接受任何格式的美国手机号码作为输入,并可选择接受第二个参数 - 如果您想要输出的手机号码格式看起来漂亮,则将其设置为 true。如果提供的号码不是手机号码,则简单地返回 false。如果检测到手机号码,则返回整个经过清理的号码,而不是 true。
function isValidMobile(num,format) {
if (!format) format=false
var m1 = /^(\W|^)[(]{0,1}\d{3}[)]{0,1}[.]{0,1}[\s-]{0,1}\d{3}[\s-]{0,1}[\s.]{0,1}\d{4}(\W|$)/
if(!m1.test(num)) {
return false
}
num = num.replace(/ /g,'').replace(/\./g,'').replace(/-/g,'').replace(/\(/g,'').replace(/\)/g,'').replace(/\[/g,'').replace(/\]/g,'').replace(/\+/g,'').replace(/\~/g,'').replace(/\{/g,'').replace(/\*/g,'').replace(/\}/g,'')
if ((num.length < 10) || (num.length > 11) || (num.substring(0,1)=='0') || (num.substring(1,1)=='0') || ((num.length==10)&&(num.substring(0,1)=='1'))||((num.length==11)&&(num.substring(0,1)!='1'))) return false;
num = (num.length == 11) ? num : ('1' + num);
if ((num.length == 11) && (num.substring(0,1) == "1")) {
if (format===true) {
return '(' + num.substr(1,3) + ') ' + num.substr(4,3) + '-' + num.substr(7,4)
} else {
return num
}
} else {
return false;
}
}
Java 生成用于验证电话号码的正则表达式(REGEX)
另一种选择是让 Java 生成一个 REGEX,匹配从列表中读取的所有电话号码变体。这意味着在下面的代码上下文中看到的名为 validPhoneNumbersFormat 的列表决定哪种电话号码格式是有效的。
注意:这种类型的算法适用于处理正则表达式的任何语言。
生成 REGEX 的代码片段:
Set<String> regexSet = uniqueValidPhoneNumbersFormats.stream()
.map(s -> s.replaceAll("\\+", "\\\\+"))
.map(s -> s.replaceAll("\\d", "\\\\d"))
.map(s -> s.replaceAll("\\.", "\\\\."))
.map(s -> s.replaceAll("([\\(\\)])", "\\\\$1"))
.collect(Collectors.toSet());
String regex = String.join("|", regexSet);
代码片段上下文:
public class TestBench {
public static void main(String[] args) {
List<String> validPhoneNumbersFormat = Arrays.asList(
"1-234-567-8901",
"1-234-567-8901 x1234",
"1-234-567-8901 ext1234",
"1 (234) 567-8901",
"1.234.567.8901",
"1/234/567/8901",
"12345678901",
"+12345678901",
"(234) 567-8901 ext. 123",
"+1 234-567-8901 ext. 123",
"1 (234) 567-8901 ext. 123",
"00 1 234-567-8901 ext. 123",
"+210-998-234-01234",
"210-998-234-01234",
"+21099823401234",
"+210-(998)-(234)-(01234)",
"(+351) 282 43 50 50",
"90191919908",
"555-8909",
"001 6867684",
"001 6867684x1",
"1 (234) 567-8901",
"1-234-567-8901 x1234",
"1-234-567-8901 ext1234",
"1-234 567.89/01 ext.1234",
"1(234)5678901x1234",
"(123)8575973",
"(0055)(123)8575973"
);
Set<String> uniqueValidPhoneNumbersFormats = new LinkedHashSet<>(validPhoneNumbersFormat);
List<String> invalidPhoneNumbers = Arrays.asList(
"+210-99A-234-01234", // FAIL
"+210-999-234-0\"\"234", // FAIL
"+210-999-234-02;4", // FAIL
"-210+998-234-01234", // FAIL
"+210-998)-(234-(01234" // FAIL
);
List<String> invalidAndValidPhoneNumbers = new ArrayList<>();
invalidAndValidPhoneNumbers.addAll(invalidPhoneNumbers);
invalidAndValidPhoneNumbers.addAll(uniqueValidPhoneNumbersFormats);
Set<String> regexSet = uniqueValidPhoneNumbersFormats.stream()
.map(s -> s.replaceAll("\\+", "\\\\+"))
.map(s -> s.replaceAll("\\d", "\\\\d"))
.map(s -> s.replaceAll("\\.", "\\\\."))
.map(s -> s.replaceAll("([\\(\\)])", "\\\\$1"))
.collect(Collectors.toSet());
String regex = String.join("|", regexSet);
List<String> result = new ArrayList<>();
Pattern pattern = Pattern.compile(regex);
for (String phoneNumber : invalidAndValidPhoneNumbers) {
Matcher matcher = pattern.matcher(phoneNumber);
if(matcher.matches()) {
result.add(matcher.group());
}
}
// Output:
if(uniqueValidPhoneNumbersFormats.size() == result.size()) {
System.out.println("All valid numbers was matched!\n");
}
result.forEach(System.out::println);
}
}
输出:
All valid numbers was matched!
1-234-567-8901
1-234-567-8901 x1234
1-234-567-8901 ext1234
...
...
...
我选择了下面的正则表达式,但是当我复制和粘贴电话号码时它没有起作用。
/^(\+?\d{0,4})?[ -]?(\(?\d{3}\)?)[ -]?(\(?\d{3}\)?)[ -]?(\(?\d{4}\)?)?$/
‑
而不是-
)。所以我又修改了正则表达式,将它也加进去了。/^(\+?\d{0,4})?[ -‑]?(\(?\d{3}\)?)[ -‑]?(\(?\d{3}\)?)[ -‑]?(\(?\d{4}\)?)?$/
True
,但你真正想要的只是一个正确的电话号码。对于任何试图清理网页或手机应用程序中最终用户输入的电话号码的人,我建议只需编写4或5行代码,逐个字符从左到右进行处理并且删除所有非数字字符。(303)873-9919
变成了3038739919
。删除所有非数字字符后,您可以在正确的位置插入(点.
),插入(连字符-
)或斜杠。 - Samuel Muldoon