数字的正则表达式,除非所有数字都相同

时间:2014-08-08 07:25:43

标签: php regex

我需要帮助来编写一个正则表达式来匹配数字,这些数字可以用空格或破折号分成几个部分,例如:

606-606-606
606606606
123 456-789

但是,如果该号码的所有数字相同(或除了[0-9 -]之外还有其他任何字符),则应拒绝匹配:

111 111 111
111111111
123456789a

如果不允许使用空格/破折号,则正则表达式很简单:

/^(\d)(?!\1*$)\d*$/

但是我如何在数字中允许破折号和空格?

修改

我如何允许同一个正则表达式中的字母(仍然允许使用破折号和空格),例如:

aaaaa - 这不行

aa-aaa-aaa-aaaaa - 这不行

ababab - 没关系

ab-ab-ab - 没关系

此规则仅检查数字。

^(?!(?:(\d)\1+[ -]*)+$)\d[\d- ]+$

2 个答案:

答案 0 :(得分:2)

通过此正则表达式可以实现所需的结果:

^(?!(?:(\d)\1+[ -]*)+$)\d[\d- ]+$

Live demo

<强>说明

^               # Start of string
(?!             # Negative Lookahead to check duplicate numbers
    (?:         # Non-capturing group
        (\d)    # Capture first digit
        \1+     # More digits same as lately captured one
        [ -]*   # Any spaces and dashes between
    )+          # One or more of what's captured up to now
    $           # End of string
)               # End of negative lookahead
\d              # Start of match with a digit
[\d- ]+         # More than one digit/dash/space
$               # End of string

这个正则表达式背后的理论是使用一个环视来检查字符串是否包含基于第一个捕获的数字的任何重复数字。如果我们在这个环视中没有匹配,那么匹配它。

答案 1 :(得分:0)

即使你可以,我想知道正则表达式是否是解决这个问题的正确工具。想象一下,你的开发人员试图理解你的代码,你有多少时间授予他们?更糟糕的是,如果你需要改变规则怎么办?

带有一些评论的小功能可以让他们开心......

function checkNumberWithSpecialRequirements($number)
{
    // ignore given set of characters
    $cleanNumber = str_replace([' ', '-'], '', $number);

    // handle empty string
    if ($cleanNumber == '')
        return false;

    // check whether non-digit characters are inside
    if (!ctype_digit($cleanNumber))
        return false;

    // check if a character differs from the first (not all equal)
    for ($index = 1; $index < strlen($cleanNumber); $index++)
    {
        if ($cleanNumber[$index] != $cleanNumber[0])
            return true;
    }
    return false;
}