我遇到了超过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
答案 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并继续完成。
编辑:我明白了,我明白了。您可能没有意识到命名组仍在编号。