Java正则表达式 - 组合表达式

时间:2014-06-21 15:21:23

标签: java regex

我正在尝试使用正则表达式编写返回信用卡供应商的代码,这似乎有用,例如:

// 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 "";
}

3 个答案:

答案 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}).*

DEMO

答案 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