我正在尝试使用正则表达式编写返回信用卡供应商的代码,这似乎有用,例如:
// Visa - always begins digit 4, 13 or 16 digits long
^[4].{12}|^[4].{15}
// Visa Electron - begin with the code pattern, 16 digits long
4026.{12}|417500.{10}|4405.{12}|4508.{12}|4844.{12}|4913.{12}|4917.{12}
所以对于一个方法isVisa我希望正则表达式说"根据Visa正则表达式返回Visa,而不是Visa Electron"
此代码不起作用:
public static String isVisa(String number) {
Pattern p = Pattern.compile("^[4].{12}|^[4].{15}&&(!4026.{12}|!417500.{10}|!4405.{12}|!4508.{12}|!4844.{12}|!4913.{12}|!4917.{12})");
Matcher m = p.matcher(number);
if (m.matches()) return "Visa";
else return "";
}
答案 0 :(得分:1)
matches()
方法针对整个字符串验证正则表达式,因此您不需要开始^
和结束$
锚点。此外,正则表达式引擎将这些字符&!
与文字进行匹配,您似乎正在尝试将它们用作运算符。
要忽略这些模式,您可以使用否定前瞻来实现此目标。
(?!.*(?:(?:4026|4405|4508|4844|4913|4917).{12}|417500.{10}))(?=4.{12}|4.{15}).*
示例:这会返回前两个true
,因为其余部分对您的案例无效。
String[] numbers = { "4000236512341234", "4000222213232222", "4026122222222222",
"4175000000000000", "4405343434344343", "4508111111111111",
"4844000000000000", "4913000000000000", "4917000000000000" };
Pattern p = Pattern.compile("(?!.*(?:(?:4026|4405|4508|4844|4913|4917).{12}|417500.{10}))(?=4.{12}|4.{15}).*");
for (String x: numbers) {
Matcher m = p.matcher(x);
System.out.println(m.matches());
}
<强>输出强>:
true
true
false
false
false
false
false
false
false
答案 1 :(得分:0)
使用正面和负面前瞻来检查以某些数字开头的行,并且不会以某些特定数字开头。
^(?!417500.{10}|4026.{12}|4405.{12}|4508.{12}|4844.{12}|4913.{12}|4917.{12})(?=4.{12}|4.{15}).*
答案 2 :(得分:0)
你可以使用一个非常简单易懂的正则表达式:
4026.{12}|417500.{10}|4405.{12}|4508.{12}|4844.{12}|4913.{12}|4917.{12}|([4].{12}|[4].{15})
这将匹配所有Visa Electron模式而不捕获任何内容。当你得到一个匹配时,检查捕获组1不是null
,因为它是Visa。
有关该技术的详细解释,请参阅this answer。