Java 正则表达式密码验证

Java 正则表达式密码验证,java,regex,Java,Regex,我如何得到它,以便它检查字符串中的2个或更多数字?调用字符串s上的匹配项 s.matches("^[a-zA-Z0-9]{8,}$"); 匹配两次: s.matches("^[a-zA-Z0-9]{8,}$"); s.matches("[0-9].*[0-9]"); 使用如下结果: if ( s.matches("^[a-zA-Z0-9]{8,}$") && s.matches("[0-9].*[0-9]") ) { # password is valid } 我真

我如何得到它,以便它检查字符串中的2个或更多数字?调用字符串s上的匹配项

s.matches("^[a-zA-Z0-9]{8,}$");
匹配两次:

s.matches("^[a-zA-Z0-9]{8,}$");
s.matches("[0-9].*[0-9]");
使用如下结果:

if ( s.matches("^[a-zA-Z0-9]{8,}$") && s.matches("[0-9].*[0-9]") ) {
    # password is valid
}

我真的看不出有什么好的理由用正则表达式检查字符串的长度——保持简单始终是个好主意,但特别是对于正则表达式,将所有内容都放入完全不可读的字符串(可能有一些奇怪的边缘)的诱惑是相当诱人的

只需对长度使用length方法,类似于“\w*?\d\w*?\d\w*” 请注意,.*是贪婪的,所以不要忘记?在它之后\d在java中表示一个数字-我不认为在unicode中有任何情况下您会在[0-9]中错过-但安全性比抱歉要好

已编辑为使用\w而不是。(仅限单词字符,即[a-zA-Z_0-9])

尝试以下操作:
(?:^\s+)(\w{8,})(?编辑

不要使用
匹配
,而是使用
查找
(读取)

matches方法尝试根据模式匹配整个输入序列。>

这就是为什么
\d.*\d
不能与
a2a2a

find方法扫描输入序列,寻找与模式匹配的下一个子序列

这就是你需要的

您只需测试是否有两个数字介于
\d.*\d
之间:

import java.util.regex.*;
class TwoDigits { 
    public static void main( String ... args ) { 
        Pattern pattern = Pattern.compile("\\d.*\\d");
        Matcher matcher = pattern.matcher( args[0]  );  
        System.out.println("Matched ( found ) ? = " + matcher.find());
    }
}
但也许我遗漏了一些东西,为什么你不试试,告诉我们失败的地方呢

C:\java>java TwoDigits ""
Matched ( found ) ? = false

C:\java>java TwoDigits "a"
Matched ( found ) ? = false

C:\java>java TwoDigits "1a1"
Matched ( found ) ? = true

C:\java>java TwoDigits "1a"
Matched ( found ) ? = false

C:\java>java TwoDigits "a1a"
Matched ( found ) ? = false

C:\java>java TwoDigits "a1a1"
Matched ( found ) ? = true

C:\java>java TwoDigits "2a2"
Matched ( found ) ? = true

C:\java>java TwoDigits "2aaa2"
Matched ( found ) ? = true

C:\java>java TwoDigits "2aaaaaaaaaaaaaaa2"
Matched ( found ) ? = true

C:\java>java TwoDigits "2aaaaaaaaaaaaaaa"
Matched ( found ) ? = false

C:\java>java TwoDigits "2aaaaaa2aaaaaaaaaa"
Matched ( found ) ? = true

C:\java>java TwoDigits "a3aaaaa2aaaaaaaaaa"
Matched ( found ) ? = true
这应该可以

^(?=.*[0-9].*[0-9])[a-zA-Z0-9]{8,}$
我所做的唯一更改是添加这个
(?=.[0-9].[0-9])
,这是一个积极的前瞻,将尝试查找密码中的前两位数字。如果满足,则正则表达式将照常进行

现在,我想我应该指出,正则表达式不允许使用特殊字符(标点符号等)。实际上,有些人喜欢在密码中输入像这样的奇怪字符

<> P>所以你可以考虑更多类似的事情…

^(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9]).{8,}$
这将允许使用特殊字符,同时还确保密码中至少存在一个大写字母、一个小写字母和一个数字。这只是我不久前编写的强密码正则表达式的一个示例,如果您愿意,您当然可以稍微放宽这些限制。

这怎么样

private Pattern p1  = Pattern.compile("^\\w{8,}$");
private Pattern p2  = Pattern.compile("\\d+(.*)?\\d+");

private boolean match(String s) {
    return p1.matcher(s).find() && p2.matcher(s).find();
}

@Test
public void testPassword() {
    assertTrue("length at least 8", match("2aaaaaa2"));
    assertTrue("length at least 8", match("aaaaaaa22"));
    assertTrue("length at least 8", match("22aaaaaaa"));
    assertTrue("length at least 8", match("aa2aa2aaa"));

    assertFalse("length less than 8", match("2aa2aaa"));
    assertFalse("one digit", match("aa2aaaaa"));
    assertFalse("no digits", match("aaaaaaaa"));
}

不起作用。返回s.matches(“^[a-zA-Z0-9]{8,}$”)和s.matches(“[0-9].[0.9]”);为“2aaaa2”返回false。它应该检查是否有2个或更多的数字以及最小长度为8的字符串。什么不起作用?您必须使用这两个语句的返回值。@释放:第一个语句检查最小长度。它为“2aaaa2”返回false因为它包含7个字符,并且7@spintheblack:否。
^
$
元字符用于匹配字符串的开头和结尾。第二个正则表达式缺少它们。@Skurmedel Java的正则表达式实现稍有不同,因为match方法不消耗所有输入。因此
\d.\d
不“匹配”
a2aa2a
(返回false),但使用
find()
确实有效。要在Java中检查数字,必须使用
\p{Nd}
。如果您只想
[0-9]
,那当然不同。您有一些示例输入吗?@tchrist我发现您在几乎每个正则表达式问题中都纠正了这个错误,这很有趣:)(没有抱怨——在你注意到之前我没有意识到区别)@Tim有什么区别呢?@OscarRyz\p{Nd}包含另一个,包括苏联的U+0968(२).该正则表达式没有找到字符串是否只包含字母数字字符和至少两位数字?不过,同意您的长度检查。+1@Tim,我本来想在答案中提到这一点,但不想听起来像n00b。现在答案看起来很核心!!是的!(只要它有效)“核心”不是我要用的词。:D和no,它不起作用。.NET是仅有的两种支持无限可变长度查找的正则表达式风格之一,而另一种不是Java;这种检查应该在前瞻中进行。为什么要在两端检查一个空白字符,更不用说一个或多个?甚至连锚都不需要在这种情况下,因为OP使用的是
matches()
方法,它隐式地将匹配锚定在两端。
(*)
?你在为共振级联场景巡游,伙计。呃,我的意思是灾难性的回溯,当然!()+1:令人惊讶的是,这不必如此复杂!