【发布时间】:2011-03-22 10:09:10
【问题描述】:
编辑: 我已经混合并修改了下面给出的两个答案,以形成完整的功能,现在可以完成我想要的功能,然后......所以我想我' d张贴在这里,以防其他人来寻找同样的东西。
/*
* Function to analyze string against many popular formatting styles of phone numbers
* Also breaks phone number into it's respective components
* 3-digit area code, 3-digit exchange code, 4-digit subscriber number
* After which it validates the 10 digit US number against NANPA guidelines
*/
function validPhone($phone) {
$format_pattern = '/^(?:(?:\((?=\d{3}\)))?(\d{3})(?:(?<=\(\d{3})\))?[\s.\/-]?)?(\d{3})[\s\.\/-]?(\d{4})\s?(?:(?:(?:(?:e|x|ex|ext)\.?\:?|extension\:?)\s?)(?=\d+)(\d+))?$/';
$nanpa_pattern = '/^(?:1)?(?(?!(37|96))[2-9][0-8][0-9](?<!(11)))?[2-9][0-9]{2}(?<!(11))[0-9]{4}(?<!(555(01([0-9][0-9])|1212)))$/';
//Set array of variables to false initially
$valid = array(
'format' => false,
'nanpa' => false,
'ext' => false,
'all' => false
);
//Check data against the format analyzer
if(preg_match($format_pattern, $phone, $matchset)) {
$valid['format'] = true;
}
//If formatted properly, continue
if($valid['format']) {
//Set array of new components
$components = array(
'ac' => $matchset[1], //area code
'xc' => $matchset[2], //exchange code
'sn' => $matchset[3], //subscriber number
'xn' => $matchset[4], //extension number
);
//Set array of number variants
$numbers = array(
'original' => $matchset[0],
'stripped' => substr(preg_replace('[\D]', '', $matchset[0]), 0, 10)
);
//Now let's check the first ten digits against NANPA standards
if(preg_match($nanpa_pattern, $numbers['stripped'])) {
$valid['nanpa'] = true;
}
//If the NANPA guidelines have been met, continue
if($valid['nanpa']) {
if(!empty($components['xn'])) {
if(preg_match('/^[\d]{1,6}$/', $components['xn'])) {
$valid['ext'] = true;
}
}
else {
$valid['ext'] = true;
}
}
//If the extension number is valid or non-existent, continue
if($valid['ext']) {
$valid['all'] = true;
}
}
return $valid['all'];
}
【问题讨论】:
-
我觉得有问题。您的格式允许区号是可选的,但是 nanpa 模式(我认为是正确的)需要有一个正确的区号。此外,如果没有给出区号,但有 给出了扩展名,该怎么办。当您剥离原始号码时,您会删除非数字,然后盲目地抓取包含扩展名的前 10 位数字。确保电话号码符合 NANPA 的唯一方法是知道区号,所以我觉得必须有区号才能返回 true。见:rubular.com/r/xxoCmSft8H
-
另外,format_pattern 不允许前导 1,但 nanpa 模式允许。
-
另外,上面的 NANPA 模式有“(?”在它里面,这不是一个正确的正则表达式模式。我假设你的意思是“(?:”。顺便说一句,我一直放的唯一原因这些 cmets 是因为这是迄今为止在互联网上找到的最好的编译 :)。我正在尝试自己使用它并帮助其他谷歌用户。
标签: php regex validation phone-number