Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/364.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/4/regex/18.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 正则表达式无法正常工作_Java_Regex - Fatal编程技术网

Java 正则表达式无法正常工作

Java 正则表达式无法正常工作,java,regex,Java,Regex,我使用以下正则表达式。 (?=.+[a-z])(?=.+[a-z])(?=.+[^a-zA-z])。{8,} 我的目标是拥有一个具有以下4个属性中的3个属性的密码 大写字符、小写字符、数字、特殊字符 我正在使用and来测试带有以下输入的表达式 P@55w0rd password1P Password1 paSSw0rd 所有这些都应该通过,但只有第二个和第四个在通过,而且所有这些都在通过 我还使用以下代码进行验证 private void doValidate(String inputStr,

我使用以下正则表达式。 (?=.+[a-z])(?=.+[a-z])(?=.+[^a-zA-z])。{8,}

我的目标是拥有一个具有以下4个属性中的3个属性的密码

大写字符、小写字符、数字、特殊字符

我正在使用and来测试带有以下输入的表达式

P@55w0rd
password1P
Password1
paSSw0rd
所有这些都应该通过,但只有第二个和第四个在通过,而且所有这些都在通过

我还使用以下代码进行验证

private void doValidate(String inputStr,String regex) {
    Pattern pattern = Pattern.compile(regex);
    if(!pattern.matcher(inputStr).matches()){
        String errMessage = "";
        throw new UniquenessConstraintViolatedException(errMessage);
    }
}
此代码无法验证应通过的“Password1”。 就表达而言,我是这样理解的

must have lower (?=.+[a-z])
must have upper (?=.+[A-Z])
must have non alpha (?=.+[^a-zA-Z])
must be eight characters long .{8,}
谁能告诉我我做错了什么


提前感谢。

您的正则表达式现在说您必须有1个或多个小写字符,后跟1个或多个大写字符,后跟1个或多个大写或小写字符,后跟8个或更多字符

正则表达式不能执行和,除非指定特定字符的显示位置。您基本上需要将正则表达式的每个部分拆分为自己的正则表达式,并检查每个正则表达式。您可以使用Java拥有的任何字符串长度方法来检查长度(很抱歉,我不是Java开发人员,所以我不知道它是什么)

伪代码:

if( regexForLower && regexForUpper && regexForSpecial && string.length == 8 ) {
     // pass
}

正如我在评论中所说,第0位大写字母被忽略了

这是一个四个密码都匹配的正则表达式

(?=.+\\d)(?=.+[a-z])(?=\\w*[A-Z]).{8,}

本质上,应该归咎于
+
子表达式,它们应该是
*
。否则,先行部分将查找小写、大写或非alpha,但如果每个对应类型的字符是字符串中的第一个字符,则该字符不计算在内。因此,您验证的不是密码,而是第一个字符被截断的密码。虽然@Cfreak是不对的,但他很接近——你所做的事情在普通正则表达式中是不可能的,你必须使用他的建议。使用组-
(?=)
-可以执行您需要的操作。不过,就我个人而言,我更愿意像@Cfreak所建议的那样编写代码——代码更可读,您的意图也更清晰。复杂的正则表达式往往很难编写,但经过一段时间后几乎无法读取、调试或改进。

我不会使用这样的正则表达式

  • 这很难理解
  • 难以调试
  • 难以扩展
  • 你对它的结果无能为力
如果你想告诉客户他的密码有什么问题,你必须再次调查密码。在现实环境中,您可能希望支持来自外国语言环境的字符

import java.util.*;
/**
    Pwtest

    @author Stefan Wagner
    @date Fr 11. Mai 20:55:38 CEST 2012
*/
public class Pwtest
{

    public int boolcount (boolean [] arr) {
        int sum = 0;
        for (boolean b : arr) 
            if (b) 
                ++sum;
        return sum;
    }

    public boolean [] rulesMatch (String [] groups, String password) {
        int idx = 0;
        boolean [] matches = new boolean [groups.length];
        for (String g: groups) {
            matches[idx] = (password.matches (".*" + g + ".*"));
            ++idx;
        }
        return matches;     
    }

    public Pwtest ()
    {
        String [] groups = new String [] {"[a-z]", "[A-Z]", "[0-9]", "[^a-zA-Z0-9]"};
        String [] pwl = new String [] {"P@55w0rd", "password1P", "Password1", "paSSw0rd", "onlylower", "ONLYUPPER", "1234", ",:?!"};
        List <boolean[]> lii = new ArrayList <boolean[]> ();
        for (String password: pwl) {
            lii.add (rulesMatch (groups, password)); 
        }

        for (int i = 0 ; i < lii.size (); ++i) {
            boolean [] matches = lii.get (i); 
            String pw = pwl[i];
            if (boolcount (matches) < 3) {
                System.out.print ("Password:\t" + pw + " violates rule (s): ");
                int idx = 0; 
                for (boolean b: matches) {
                    if (! b) 
                        System.out.print (groups[idx] + " "); 
                    ++idx;
                }
                System.out.println (); 
            }
            else System.out.println ("Password:\t" + pw + " fine ");
        }
    }

    public static void main (String args[])
    {
        new Pwtest ();
    }
}

@Vulcan,但或将意味着它将匹配所有这些。问题是你的首字母大写字母被忽略了。如果在字符串中的任何其他位置添加大写字母,则密码1和密码3都可以使用。数字检查在哪里?(?=.+[^a-zA-Z])这会查找任何非字母字符,因此数字或特殊字符不必。我现在有了一个模式,除了第一个,它可以接受所有的模式,但这是因为@符号。谢谢大家的快速回复。解决了我的问题。我之所以使用正则表达式将密码规则外部化,以便以后可以在不重新部署应用程序的情况下对其进行更改。再次感谢所有的回复。
Password:   P@55w0rd fine 
Password:   password1P fine 
Password:   Password1 fine 
Password:   paSSw0rd fine 
Password:   onlylower violates rule (s): [A-Z] [0-9] [^a-zA-Z0-9] 
Password:   ONLYUPPER violates rule (s): [a-z] [0-9] [^a-zA-Z0-9] 
Password:   1234 violates rule (s): [a-z] [A-Z] [^a-zA-Z0-9] 
Password:   ,:?! violates rule (s): [a-z] [A-Z] [0-9] 
Password:   Übergrößen345 fine 
Password:   345ÄÜö violates rule (s): [a-z] [A-Z]