2012-01-05 90 views
4

我有一个Java应用程序,用户必须指定一个PIN登录时要创建PIN,只有3个要求:正则表达式来检查重复数字

  • 必须是6位数字:

    \\d{6} 
    
  • 必须没有4个或更多序列号:

    \\d*(0123|1234|2345|3456|4567|5678|6789)\\d* 
    
  • 必须不具有数字重复3或以上的Ti MES(如000957或623334或514888): 这是我坚持...

我曾尝试:

\\d*(\\d)\\1{3}\\d* 

但我相信\1是看初始匹配到\d*不是(\d)的第二个匹配。


答用于: 我已经更新到使用:

\\d{6} 
(0123|1234|2345|3456|4567|5678|6789|9876|8765|7654|6543|5432|4321|3210) 
\\d*?(\\d)\\1{2,}\\d* 

为了满足最初规定的要求加我没有想到的几个!感谢所有的帮助

+4

这个过程作为一个整体,更好地在正则表达式之外完成。 *虽然酷,正则表达式不是你唯一的工具孩子。* – 2012-01-05 18:41:30

+0

你的建议如何处理? – 2012-01-05 18:49:34

+1

'010203'呢?也就是说,三个或更多相同的数字,但不是连续的? – 2012-01-05 18:50:32

回答

8

你的正则表达式稍微偏离,因为第一个\ d将匹配第一个数字。之后你只想匹配2个。

\\d*(\\d)\\1{2}\\d* 

应该这样做。

快速编辑: 如果你想在序列匹配2个或更多的数字,只需添加一个逗号你计数,而无需指定最大数量:

\\d*(\\d)\\1{2,}\\d* 

或者至少,这部作品在Perl。让我们知道你是如何去的。

+0

非常完美!我完全忘记了第一场比赛! Brain Fart for the lost :-( – 2012-01-05 18:49:08

+1

另外,你想让第一个\\ d *非贪婪,它应该减少在你的正则表达式中找到一个匹配的步骤的数量,因为它是,因为它会扫描整个数字,然后通过字符串向后工作 – Rohaq 2012-01-05 19:05:46

+0

一个例子本来就不错:): \\ d *?(\\ d)\\ 1 {2,} \\ d * 享受! – Rohaq 2012-01-05 19:11:59

4

是否要阻止三个重复的数字或一般超过三个数字(如在“112213”中)?

如果后者的话,正则表达式可能不是一个最好的解决办法:

public static boolean validate(String pin){ 
    if (pin == null || pin.length() != 6) 
     return false; 

    int[] count = new int[10]; 
    for (int i = 0; i < pin.length(); i++) { 
     char c = pin.charAt(i); 
     if(!Character.isDigit(c)) 
      return false; 

     if (++count[c - '0'] > 3) 
      return false; 
    } 

    return true; 
} 
+0

对于非正则表达式解决方案+1。 – 2012-01-05 19:02:49

+0

非正则表达式的解决方案很好,但问题确实表明答案应该是一个正则表达式。如果提供非正则表达式的答案,支持为什么答案可能是更好的解决方案将是有益的! – 2012-01-10 23:31:26

+0

@ D.R .:如前所述,我写了一个解决方案来捕捉三个一般的数字(也是非重复的数字),因为这个问题在没有以下讨论的情况下一直是模糊的。这是不可能的正则表达式恕我直言。也许我的代码会帮助别人,而OP会发现这个线程有类似的问题:-) – Matthias 2012-01-11 18:50:20

0

嗯,你的例子,你的文字不匹配。你说它不能重复3次以上。 000是正好3次的重复,所以它应该是正常的,但是0000是重复4次,超过3次所以不应该重复。要匹配文本的要求,你的正则表达式应该是

.*(\d)\1{3}.* 

其中在Java字符串应该是

".*(\\d)\\1{3}.*" 

这与你有什么,所以也许你只是误解的措辞。

注:我喜欢这个测试我的正则表达式中的Java:http://www.regexplanet.com/simple/index.html

1

我想:

  1. 检查长度== 6
  2. 检查\ d +
  3. 频率计数每一个数字:

int[] f = new int[10]; 
int pow10 = 1; 
int npow10 = 10; 
int nmod = 0, nmod2 = n % 10; 
while(i < 6) do 
    int iDigit = (nmod2 - nmod)/pow10 
    if(++f[iDigit] > 2) 
    return false; 
    pow10 = npow10; 
    npow10 *= 10; 
    nmod = nmod2; 
    nmod2 = n % npow10; 
    i++; 
end 
return true; 

+0

对于非正则表达式的解决方案+1。 – 2012-01-05 19:05:11

1

看起来你正在做三个单独的正则表达式匹配,大概否定了第二个和第三个匹配的结果。在这种情况下,这应该做的伎俩:

pinString.matches("^\\d{6}$") 

!pinString.matches("^.*?(?:0123|1234|2345|3456|4567|5678|6789).*$") 

!pinString.matches("^.*?(\\d)\\1{2}.*$") 

随着matches()方法,你并不真正需要的锚(^$),但只要不伤害他们让你的意图更加明显。此外,第一个正则表达式确保所有六个字符都是数字,所以使用.而不是\\d作为其他两个空间填充符是安全的。