简体   繁体   English

正则表达式特殊字符在Java中的字符串开头不起作用

[英]Regular expression special characters not working at the starting of the string in java

After trying other variations, I use this regular expression in Java to validate a password: 在尝试了其他变体之后,我在Java中使用此正则表达式来验证密码:

PatternCompiler compiler = new Perl5Compiler();
PatternMatcher matcher = new Perl5Matcher();
pattern = compiler.compile("^(?=.*?[a-zA-Z])(?![\\\\\\\\_\-])(?=.*?[0-9])([A-Za-z0-9-/-~]
[^\\\\\\\\_\-]*)$");

But it still doesn't match my test cases as expected: 但这仍然与我的测试用例不符:

Apr@2017 match Apr@2017比赛
$$Apr@2017 no match, but it should match $$Apr@2017没有匹配项,但应匹配
!!Apr@2017 no match, but it should match !!Apr@2017没有匹配项,但应该匹配
!#ap#2017 no match, but it should match !#ap#2017没有匹配项,但应该匹配
-Apr@2017 it should not match -Apr@2017不匹配
_Apr@2017 it should not match _Apr@2017它不应该匹配
\\Apr@2017 it should not match \\Apr@2017它不应该匹配

Except three special characters - _ \\ remaining, all should match at the start of the string. 除了三个特殊字符-剩余的_ \\其他所有字符都应在字符串开头匹配。

Rules: 规则:

  • It should accept all special characters any number of times except above three symbols. 除三个符号外,它应多次接受所有特殊字符。

  • It must and should contain one number and Capital letter at any place in the string. 它必须并且应该在字符串的任何位置包含一个数字和大写字母。

You have two rules, why not create more than one regular expression? 您有两个规则,为什么不创建多个正则表达式?

It should accept all special characters any number of times except above three symbols. 除三个符号外,它应多次接受所有特殊字符。

For this one, make sure it does not match [-\\\\_] (note that the - is the first character in the character class or it will be interpreted as a range. 为此,请确保它与[-\\\\_] 匹配(请注意-是字符类中的第一个字符,否则它将被解释为范围。

It must and should contain one number and Capital letter at any place in the string. 它必须并且应该在字符串的任何位置包含一个数字和大写字母。

For this one, make sure it matches [AZ] and [0-9] 为此,请确保其匹配[AZ][0-9]

To make it easy to modify and extend, do some abstraction: 为了便于修改和扩展,请进行一些抽象:

class PasswordRule
{
    private Pattern pattern;
    // If true, string must match, if false string must not match
    private boolean shouldMatch;

    PasswordRule(String patternString, boolean shouldMatch)
    {
        this.shouldMatch = shouldMatch;
        this.pattern = compiler.compile(patternString);
    }

    boolean match(String passwordString)
    {
        return pattern.matches(passwordString) == shouldMatch;
    }
}

I don't know or care if I have the API to Perl5 matching correct in the above, but you should get the idea. 我不知道或不在乎上面是否有与Perl5匹配的API,但是您应该明白这一点。 Then your rules go in an array 然后您的规则进入数组

PasswordRule rules[] = 
{
    PasswordRule("[-\\\\_]", false),
    PasswordRule("[A-Z]", true),
    PasswordRule("[0-9]", true)
};

boolean passwordIsOk(String password)
{
    for (PasswordRule rule : rules)
    {
        if (!rule.match(password) 
        {
            return false;
        }
    }
    return true;
}

Using the above, your rules are far more flexible and modifiable than one monstrous regular expression. 使用上述方法,您的规则比一个怪异的正则表达式要灵活得多,并且可以修改。

You seem to need 你好像需要

"^(?=[^a-zA-Z]*[a-zA-Z])(?=[^0-9]*[0-9])[^\\\\_-]*$"

See the regex demo 正则表达式演示

  • ^ - start of string ^ -字符串的开头
  • (?=[^a-zA-Z]*[a-zA-Z]) - a positive lookahead that requires at least 1 ASCII letter ( [a-zA-Z] ) to appear after 0+ chars other than letters ( [^a-zA-Z]* ) (?=[^a-zA-Z]*[a-zA-Z]) -一个正向超前查询,需要至少1个ASCII字母( [a-zA-Z] )出现在除字母( [^a-zA-Z]*
  • (?=[^0-9]*[0-9]) - at least 1 ASCII digit (same principle of contrast as above is used here) (?=[^0-9]*[0-9]) -至少1个ASCII数字(此处使用上述相同的对比原理
  • [^\\\\\\\\_-]* - 0+ chars other than \\ (inside a Java string literal, \\ should be doubled to denote 1 literal backslash, and to match a single backslash with a regex, we need double literal backslash), _ , - [^\\\\\\\\_-]* -除\\以外的0+个字符(在Java字符串文字中, \\应该加倍以表示1个文字反斜杠,并且要将单个反斜杠与regex匹配,我们需要双重文字反斜杠) , _-
  • $ - end of string ( \\\\z might be better though as it matches at the very end of the string). $ -字符串的结尾( \\\\z可能是,虽然它在字符串结尾处匹配更好)。

Here's an alternative solution - reverse the condition. 这是一个替代解决方案-反转条件。 This regex 这个正则表达式

^(?:[^0-9]*|[^A-Z]*|[_\\-].*)$

matches non conforming passwords. 匹配符合要求的密码。 This makes it much simpler to understand. 这使它更容易理解。

It matches either 它匹配

  • a string free from digits 没有数字的字符串
  • a string free from capital letters 没有大写字母的字符串
  • a string containing either of _ , \\ or - 包含_\\-的字符串

See it illustrated here at regex101 . 参见regex101所示

There are some unclear issues remaining in your question though, so it may have to be adjusted. 不过,您的问题中还有一些不清楚的问题,因此可能需要进行调整。 (The restriction in starting character I mentioned as a comment) (我在评论中提到的起始字符的限制)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM