我一直在谷歌搜索,我没有找到我的问题的答案:
如何使用正则表达式检查字符串是否包含以下各项中的至少一个:
~`!@#$%^&*()-_=+\|[{]};:'",<.>/?
所以我至少需要一个大写字母和至少一个小字母和至少一个数字和至少一个特殊字符。
我确信答案很简单,但我找不到。非常感谢任何帮助。
答案 0 :(得分:38)
对于需要满足几个条件所有的测试,正则表达式不是很好。
因此,最简单的答案是不要试图同时测试它们,而只是依次尝试四个类中的每一个。
您的代码可能分数较慢,但它更容易阅读和维护,例如。
public boolean isLegalPassword(String pass) {
if (!pass.matches(".*[A-Z].*")) return false;
if (!pass.matches(".*[a-z].*")) return false;
if (!pass.matches(".*\\d.*")) return false;
if (!pass.matches(".*[~!.......].*")) return false;
return true;
}
编辑固定引号 - 一直在做太多该死的JS编程......
答案 1 :(得分:14)
我同意@ Alnitak的答案是最容易阅读的,但是它每次运行时都必须评估正则表达式。由于正则表达式是固定的,因此编译它们然后与它们进行比较是有意义的。 例如类似的东西:
private static final Pattern [] passwordRegexes = new Pattern[4];
{
passwordRegexes[0] = Pattern.compile(".*[A-Z].*");
passwordRegexes[1] = Pattern.compile(".*[a-z].*");
passwordRegexes[2] = Pattern.compile(".*\\d.*");
passwordRegexes[3] = Pattern.compile(".*[~!].*");
}
public boolean isLegalPassword(String pass) {
for(int i = 0; i < passwordRegexes.length; i++){
if(!passwordRegexes[i].matcher(pass).matches())
return false;
}
return true;
}
当使用10个字符的密码运行100,000次时,上述代码的速度是原来的两倍。虽然,我想现在你可以说这段代码更难读!没关系!
答案 2 :(得分:13)
这可以在java中作为单个正则表达式执行,但我个人会使用类似Mark Rhodes提供的解决方案。随着规则变得更加复杂,这将变得荒谬(如果还没有......)。
String regex = "^(?=.*?\\p{Lu})(?=.*?[\\p{L}&&[^\\p{Lu}]])(?=.*?\\d)" +
"(?=.*?[`~!@#$%^&*()\\-_=+\\\\\\|\\[{\\]};:'\",<.>/?]).*$"
^这匹配字符串的开头。这不是必须的,但我发现它有助于提高可读性和理解力。此外,使用它时,通常可以大幅提升性能,几乎不会受到惩罚。
(?= X )这称为正向前瞻。基本上我们所说的是“字符串的开头(^)必须跟着这个东西 X 才能匹配,但不要将光标前进到 X 的结尾,留在行的开头。(这是“向前看”部分。)
。*?\ p {Lu}在行开头后吃字符,直到找到大写字母。如果没有找到大写字母,这将无法匹配。我们使用\ p {Lu}代替A-Z,因为我们不希望来自世界其他地方的人举手投诉我们的软件是如何由一个无知的美国人写的。
现在我们回到行的开头(我们回去因为我们使用了前瞻)并开始搜索。*?[\ p {L}&amp;&amp; [^ \ p {Lu} ]]“所有字母,减去大写字母”的简写(因此匹配小写)。
。*?\ d +。*?[`〜!@#$%^&amp; *()\ -_ = + \\\ | \ [{\]};:'\“, &lt;。&gt; /?]重复数字和特殊字符列表。
。* $匹配其他所有内容,直到该行结束。我们这样做只是因为java中'matches'方法的语义,看看整个字符串是否与正则表达式匹配。您可以保留此部分并使用Matcher#find()方法并获得相同的结果。
The Owl is one of the best books ever written on any technical subject.阅读时间短而快。我不能推荐它。
答案 3 :(得分:7)
因为这些不会以任何特定顺序出现,所以每个必需的字符类都需要前瞻断言:
(?=.*[A-Z])(?=.*[a-z])(?=.*[0-9])(?=.*[~!@#$%\^&*()\-_=+\|\[{\]};:'",<.>/?])
(注意:因为反斜杠,插入符号,连字符和方括号在一个范围内可能是特殊的,如果它们出现在范围内,它们应该反斜杠转义,如第四个先行断言所示。)
如果您的正则表达式变体支持x
修饰符,则可以使用空格和注释使此构造更具可读性。在java.util.regex
中,您可以执行以下操作:
(?x) # extended syntax
(?=.*[A-Z]) # look ahead for at least one upper case
(?=.*[a-z]) # look ahead for at least one lower case
(?=.*[0-9]) # look ahead for at least one numeral
(?=.*[~!@#$%\^&*()\-_=+\|\[{\]};:'",<.>/?])
# look ahead for at least one of the listed symbols
答案 4 :(得分:-1)
您正在寻找character classes。
^
否定该课程的其他任何人都没有)如果您想测试'this'或'that',您可以组合这些范围。例如,大写或小写字母为[A-Za-z]
。
答案 5 :(得分:-1)
\w
:用于匹配字母数字(字母可以大或小)
\W
:用于匹配特殊字符
我认为此RegEx会对您有所帮助:
[\w|\W]+
这是一个很好的RegEx Simulator,您可以使用它来构建自己的RegEx。