正则表达式识别电话号码

时间:2017-02-16 12:53:21

标签: php regex drupal-7

我有一个要求,我必须在用户提供的消息中隐藏电话号码。我已经有一个正则表达式如下:

/\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})/

但这只能识别以下格式的手机号码:

9876543210

我希望它也涵盖以下格式:

  

987 654 3210

     

9 8 7 6 5 4 3 2 1 0

     

(987)654 3210

     

(987)(654)(3210)

在上述所有格式中,空格可以用“ - ”或“。”代替。此外,'('和')'可以替换为'['和']'。

此外,是否可以识别用字符串而不是数字提及的电话号码,例如

  九八七六五四有三二二零

     

数字和字符串的任意组合

编辑:添加我的隐藏联系电话号码的功能(如果有的话):

function hide_contact_number($description) {
// Find contact number and hide it!
$regex = "/\(?([0-9]{3})\)?[-. ]?([0-9]{3})[-. ]?([0-9]{4})/";
/*$regex = "/[\([]?([0-9]{3})[\)\]]?[-. ]?[\([]?([0-9]{3})[\)\]]?[-. ]?[\([]?([0-9]{4})[\)\]]?|([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])/";*/
if(preg_match_all($regex, $description, $matches, PREG_OFFSET_CAPTURE)) {
    foreach($matches as $matchkey => $match) {
        foreach($match as $key => $value) {
            $index = 0;
            $length = 0;
            if(is_array($value)) {
                if(is_numeric($value[0]) && strlen($value[0]) >= 10) {
                    $index = $value[1];
                    $length = strlen($value[0]);
                } else if(strlen($value[1]) >= 10) {
                    $index = $value[0];
                    $length = strlen($value[1]);
                } else {
                    // TODO: Do nothing
                }
            }

            if($length > 0) {
                // length - 2 => 2 places before end of email id including 1 of index + 1
                $description = substr_replace($description, str_repeat("*", $length-2), $index+1, $length-2);
            }
        }
    }
}

return $description;

}

上述功能无法识别和隐藏我提到的所有数字序列。即使@CCH的解决方案也无济于事。这个功能有什么问题吗?

3 个答案:

答案 0 :(得分:1)

这:

  

[\([]?([0-9]{3})[\)\]]?[-. ]?[\([]?([0-9]{3})[\)\]]?[-. ]?[\([]?([0-9]{4})[\)\]]?|([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])

将匹配您的所有示例 在这里演示:
https://regex101.com/r/h9631Z/4

对于完整的php函数,请使用:

function hide_contact_number($description) {
$re = '/[\([]?([0-9]{3})[\)\]]?[-. ]?[\([]?([0-9]{3})[\)\]]?[-. ]?[\([]?([0-9]{4})[\)\]]?|([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])[-. ]([0-9])/';
$subst = '*** *** ***';
return preg_replace($re, $subst, $description);
}

您可以更改$ subst以设置将匹配替换为的内容。

此处完整演示:https://repl.it/FnSp/3

答案 1 :(得分:0)

对所有这些情况的一个快速而简单的解决方案是创建仅包含数字的时间变量。

我不知道任何PHP,但在JS(你当然可以改编它)中它会是:

aux = string.replace(/\D/g, '')

然后将你的正则表达式应用于aux变量。

匹配所有案例的正则表达式会非常难看,但我会去:

\(?\d\s*\d\s*\d\)\s*\(?\d\s*\d\s*\d\)\s*\(?\d\s*\d\s*\d\s*\d)

这个词,你可以随时做:

number = string
    .replace(/one/g, '1')
    .replace(/two/g, '2')
    .replace(/three/g, '3')
    .replace(/four/g, '4')
    .replace(/five/g, '5')
    .replace(/six/g, '6')
    .replace(/seven/g, '7')
    .replace(/eight/g, '8')
    .replace(/nine/g, '9')
    .replace(/zero/g, '0');

(你可以继续添加数字来支持,比如十,十一等......) 您还可以使用正则表达式来匹配数字和字符串的组合。例如,修改我使用的那个:

\(?d|one|two|three|four|five|six|seven|eight|nine\s*d|one|two|three|four|five|six|seven|eight|nine\s*d|one|two|three|four|five|six|seven|eight|nine\)?\s*\(?d|one|two|three|four|five|six|seven|eight|nine\s*d|one|two|three|four|five|six|seven|eight|nine\s*d|one|two|three|four|five|six|seven|eight|nine\)?\s*\(?d|one|two|three|four|five|six|seven|eight|nine\s*d|one|two|three|four|five|six|seven|eight|nine\s*d|one|two|three|four|five|six|seven|eight|nine\s*d|one|two|three|four|five|six|seven|eight|nine\)?

(我真的不建议这样做)

答案 2 :(得分:0)

为正在寻找类似解决方案的任何人发布此信息。在CCH的答案(已接受)和dquijada的帮助下,我想出了以下功能来隐藏内容中的联系电话号码。

function hide_contact_number($description) {
    $search = array('zero', 'one', 'two', 'three', 'four', 'five', 'six', 'seven', 'eight', 'nine');
    $replace = array('0', '1', '2', '3', '4', '5', '6', '7', '8', '9');
    $description = str_ireplace($search, $replace, $description);

    $regex = '/[\([]?([0-9]{3})[\)\]]?[-. ]?[\([]?([0-9]{3})[\)\]]?[-. ]?[\([]?([0-9]{4})[\)\]]?' .
    '|([0-9])[-. ]*([0-9])[-. ]*([0-9])[-. ]*([0-9])[-. ]*([0-9])[-. ]*([0-9])[-. ]*([0-9])[-. ]*([0-9])[-. ]*([0-9])[-. ]*([0-9])[-. ]*/';
    $description = preg_replace($regex, str_repeat('*', 10), $description);

    return $description;
}

FYI:这只有一个问题,即如果文本格式中提到了一个数字,它将转换为实际数字。对于。例如如果有以下行:

This one is the very good case to solve.

上述行将按如下方式转换:

This 1 is the very good case to solve.