正则表达式匹配超过4个字符

时间:2017-03-05 18:44:21

标签: c# regex

我遇到了超过4个字符的正则表达式匹配问题。我尝试了4个字符,然后返回真实的。但是,对于超过4个字符,它返回种类的错误。请让我知道那里发生了什么。

    public static string CardRegex =
        @"^(?:(?<VisaDebit>4744)|
        (?<Discover>6011)|
        (?<Amex>3[47]\d{2}))([ -]?)(?(DinersClub)(?:\d{6}\1\d{4})|(?(Amex)(?:\d{6}\1\d{5})|(?:\d{4}\1\d{4}\1\d{4})))$";
    public static CreditCardTypeType? GetCardTypeFromNumber(string cardNum)
    {
        var cardTest = new Regex(CardRegex);

        var gc = cardTest.Match(cardNum).Groups;

        if (gc[CreditCardTypeType.VisaDebit.ToString()].Success)
            return CreditCardTypeType.VisaDebit;
        if (gc[CreditCardTypeType.Discover.ToString()].Success)
            return CreditCardTypeType.Discover;
        return null;
    }

输入:4744721015347572

(?<VisaDebit>4744) ==> return VisaDebit
(?<VisaDebit>4744**7**) ==> return null

1 个答案:

答案 0 :(得分:1)

^在字符串

的开头声明当前位置

$断言字符串

末尾的当前位置

由于这些是在捕获组之外,因此输入的每个卡号必须匹配,这当然是故意的。但是,5位数字不匹配。

如果是(?:(?<VisaDebit>4744),您正在搜索此4位数字。除了上面描述的断言之外,你单独匹配这个4位数字,这就是47447不匹配的原因,它基本上超过了你断言字符串结尾的地方,除非你的一个变化匹配。

你有一个DinersClub条件(?(DinersClub)没有一个同名的组。我不知道这是否是故意的。

您的匹配模式开始时出现问题。这是你的正则表达式,没有变化。我只对其进行了格式化,以便您可以看到自己的分支。

^
(?:
  (?<VisaDebit>4744)
|
  (?<Discover>6011)
|
  (?<Amex>3[47]\d{2})
)
([ -]?)
(?(DinersClub)                 # as described above, you have no DinersClub Group
  (?:\d{6}\1\d{4})
|
  (?(Amex)
    (?:\d{6}\1\d{5})           # this is a problem similar to the analasys below
  |
    (?:\d{4}\1\d{4}\1\d{4})    # this is probably a problem
  )
)$

问题子模式analasys

\d{4}  # this is saying any 4 digits
\1     # this is a repetition of CG 1. Whatever it matched
         # not any 4 digits, but 4744
\d{4}  # any 4 digits
\1     # explained above
\d{4}  # any 4 digits

您可能永远不会将Visa条件与可匹配的数字相匹配。它正在尝试签证,意识到它不匹配,回溯,跳过发现并尝试AmEx并继续完成。

编辑:我明白了,我明白了。您可能没有意识到命名组仍在编号。