【问题标题】:Checking letter case (Upper/Lower) within a string in Java在Java中检查字符串中的字母大小写(大写/小写)
【发布时间】:2013-04-14 05:20:15
【问题描述】:

我遇到的问题是我无法让我的密码验证程序检查一个字符串以确保其中 1 个字符是大写的,一个是小写的,它将检查整个字符串其中一个并根据它正在检查的语句打印错误消息。

我已经查看了这个网站和互联网以寻找答案,但我找不到答案。这是家庭作业。

下面是我当前的代码。

import java.util.Scanner;

public class password
{
    public static void main(String[] args)
    {
        Scanner stdIn = new Scanner(System.in);
        String password;
        String cont = "y";
        char ch;
        boolean upper = false;
        boolean lower = false;

        System.out.println("Setting up your password is easy. To view requirements enter Help.");
        System.out.print("Enter password or help: ");
        password = stdIn.next();
        ch = password.charAt(0);

        while (cont.equalsIgnoreCase("y"))
        {
            while (password.isEmpty())
            {
                System.out.print("Enter password or help: ");
                password = stdIn.next();       
            }

            if (password.equalsIgnoreCase("help"))
            {
                 System.out.println("Password must meet these requirements." +
                     "\nMust contain 8 characters.\nMust contain 1 lower case letter." +
                     "\nMust contain 1 upper case letter.\nMust contain 1 numeric digit." +
                     "\nMust contain 1 special character !@#$%^&*\nDoes not contain the word AND or NOT.");

                password = "";
            }
            else if (password.length() < 8)
            {
                System.out.println("Invalid password - Must contain 8 charaters.");
                password = "";
            }
            else if (!(Character.isLowerCase(ch)))
            {
                for (int i=1; i<password.length(); i++)
                {
                    ch = password.charAt(i);

                    if (!Character.isLowerCase(ch))
                    {  
                        System.out.println("Invalid password - Must have a Lower Case character.");
                        password = "";
                    }
                }
            }
            else if (!(Character.isUpperCase(ch)))
            {
                for (int i=0; i<password.length(); i++)
                {       
                    ch = password.charAt(i);

                    if (!Character.isUpperCase(ch))
                    {
                        System.out.println("Invalid password - Must have an Upper Case character.");
                        password = "";
                    }
                }
            }
            else
            {
                System.out.println("Your password is " + password);

                System.out.print("Would you like to change your password? Y/N: ");
                cont = stdIn.next();
                password = "";
            }

            while (!cont.equalsIgnoreCase("y") && !cont.equalsIgnoreCase("n"))
            {
                System.out.print("Invalid Answer. Please enter Y or N: ");
                cont = stdIn.next();
            }
        }
    }
}

【问题讨论】:

  • 我想您想将所有这些限制应用于密码,否则如果不是这样的构造。

标签: java


【解决方案1】:

要确定一个字符串是否包含大写和小写字符,可以使用以下方法:

boolean hasUppercase = !password.equals(password.toLowerCase());
boolean hasLowercase = !password.equals(password.toUpperCase());

这允许您检查:

if(!hasUppercase)System.out.println("Must have an uppercase Character");
if(!hasLowercase)System.out.println("Must have a lowercase Character");

本质上,这是通过检查字符串是否等于其完全小写或大写等效来实现的。如果不是这样,则必须至少有一个大写或小写字符。

至于你的其他条件,可以类似的方式满足:

boolean isAtLeast8   = password.length() >= 8;//Checks for at least 8 characters
boolean hasSpecial   = !password.matches("[A-Za-z0-9 ]*");//Checks at least one char is not alpha numeric
boolean noConditions = !(password.contains("AND") || password.contains("NOT"));//Check that it doesn't contain AND or NOT

上面有合适的错误信息。

【讨论】:

  • 小编辑:password.length() &gt;= 8 因为长度 = 8 应该足够了。这正在成为我最喜欢的答案。
  • 已修复 :) 感谢您的现场。
  • 谢谢你的。因为我觉得这应该成为公认的答案,所以应该没有错误。不确定您的特殊字符测试是否正确......它会让密码包含~()-_=+ 中的任何一个,但那些不在“特殊”字符列表中。
  • 再次感谢你们两位。真的帮助我走上正轨。我很享受编程,但我以为我会在那里失去理智一秒钟。 (在我的第 5 周编程时仍然很新,他们在我的学校开始使用 Java。)
  • 希望你坚持下去。祝你未来好运:D
【解决方案2】:

快速浏览documentation on regular expression sytanx 应该会找到一些方法来判断它是否在某些时候包含小写/大写字符。

【讨论】:

    【解决方案3】:

    这样的循环:

    else if (!(Character.isLowerCase(ch)))
                {
                    for (int i=1; i<password.length(); i++)
                    {
                       ch = password.charAt(i);
    
                        if (!Character.isLowerCase(ch))
                           {  
                            System.out.println("Invalid password - Must have a Lower Case character.");
                            password = "";
                           }
                         // end if
                    } //end for
                }
    

    有一个明显的逻辑缺陷:如果第一个字符不是小写就输入它,然后测试第二个字符是否不是小写。那时你会抛出一个错误。

    相反,你应该做这样的事情(不是完整的代码,只是一个例子):

    boolean hasLower = false, hasUpper = false, hasNumber = false, hasSpecial = false; // etc - all the rules
    for ( ii = 0; ii < password.length(); ii++ ) {
      ch = password.charAt(ii);
      // check each rule in turn, with code like this:
      if Character.isLowerCase(ch) hasLower = true;
      if Character.isUpperCase(ch) hasUpper = true;
      // ... etc for all the tests you want to do
    }
    
    if(hasLower && hasUpper && ...) {
      // password is good
    } 
    else {
      // password is bad
    }
    

    当然,除了错误的逻辑之外,您提供的代码 sn-p 没有代码来测试您的“帮助”选项打印出的其他条件。正如其他答案之一所指出的,您可以考虑使用正则表达式来帮助您加快查找这些内容的过程。例如,

    hasNumber  : use regex pattern "\d+" for "find at least one digit"
    hasSpecial : use regex pattern "[!@#$%^&*]+" for "find at least one of these characters"
    

    在代码中:

    hasNumber  = password.matches(".*\\d.*");  // "a digit with anything before or after"
    hasSpecial = password.matches(".*[!@#$%^&*].*");
    hasNoNOT   = !password.matches(".*NOT.*");
    hasNoAND   = !password.matches(".*AND.*");
    

    可以以巧妙的方式组合这些东西 - 但特别是当您是 regex 新手时,最好稍微“缓慢而乏味”,并获得第一次工作的代码(另外,您将能够弄清楚六个月后你做了什么)。

    【讨论】:

    • 非常感谢您的快速回复。这完全有道理。走错了路,盯着它看了一个小时,想着如何改变它。
    • 虽然这很长,但它需要,并且只检查密码的前 8 个字符。
    • @Quirliom - 根据“帮助”文本,要求密码长度为八个字符。不是 9,不是 10。上面写着 "\nMust contain 8 characters." 也许我把它理解得太字面意思了。我会相应地更新。
    • 密码长度是我自己编写程序时的错误,省略了“至少”很容易更改 password.length 以检查字符串中的所有字符。
    • 还有一个要点,您对数字的检查将抱怨无效的转义字符,您需要转义 \ :)
    【解决方案4】:

    尽管这段代码可能超出了新手的理解,但可以使用正则表达式在一行中完成:

    boolean ok = 
        password.matches("^(?=.*[A-Z])(?=.*[!@#$%^&*])(?=.*\\d)(?!.*(AND|NOT)).*[a-z].*");
    

    【讨论】:

    • "不包含 NOT 或 AND,具有这些特殊字符之一 !@#$%^&amp;*,包含数字。是否所有这些条件都经过测试?我不认为自己是新手,但我不没看到。
    • @Floris 该问题要求断言该字符串包含至少 1 个大写字母和至少 1 个小写字母。这正是我的代码所做的。我现在注意到代码(仅)需要一个数字和一个特殊字符。答案已编辑以迎合这一点。
    • +1 表示令人敬畏和密度。我花了一段时间才说服自己可以像这样安全地链接前瞻-我认为关键是每个前瞻中的.*。还在学习中...
    • 我以前从未见过像这样使用“密度”这个词......我喜欢它!我通常使用“简洁”,但听起来有点“软”。 “密度”听起来既积极又酷。谢谢 - 你改变了我的生活:)
    • 唯一的问题是你如何告诉最终用户他们的密码的哪个方面不正确?这种方法只会说是或否。
    【解决方案5】:

    这就是我得到的:

        Scanner scanner = new Scanner(System.in);
        System.out.println("Please enter a nickname!");
        while (!scanner.hasNext("[a-zA-Z]{3,8}+")) {
            System.out.println("Nickname should contain only Alphabetic letters! At least 3 and max 8 letters");
            scanner.next();
        }
        String nickname = scanner.next();
        System.out.println("Thank you! Got " + nickname);
    

    在此处阅读正则表达式模式: https://docs.oracle.com/javase/7/docs/api/java/util/regex/Pattern.html

    【讨论】:

      【解决方案6】:

      我已将上面@Quirliom 的答案精简为可以使用的函数:

      private static boolean hasLength(CharSequence data) {
          if (String.valueOf(data).length() >= 8) return true;
          else return false;
      }
      
      private static boolean hasSymbol(CharSequence data) {
          String password = String.valueOf(data);
          boolean hasSpecial = !password.matches("[A-Za-z0-9 ]*");
          return hasSpecial;
      }
      
      private static boolean hasUpperCase(CharSequence data) {
          String password = String.valueOf(data);
          boolean hasUppercase = !password.equals(password.toLowerCase());
          return hasUppercase;
      }
      
      private static boolean hasLowerCase(CharSequence data) {
          String password = String.valueOf(data);
          boolean hasLowercase = !password.equals(password.toUpperCase());
          return hasLowercase;
      }
      

      【讨论】:

        【解决方案7】:
        package passwordValidator;
        
        import java.util.Scanner;
        
        public class Main {
            /**
             * @author felipe mello.
             */
        
            private static Scanner scanner = new Scanner(System.in);
        
             /*
             * Create a password validator(from an input string) via TDD
             * The validator should return true if
             *  The Password is at least 8 characters long
             *  The Password contains uppercase Letters(atLeastOne)
             *  The Password contains digits(at least one)
             *  The Password contains symbols(at least one)
             */
        
        
            public static void main(String[] args) {
                System.out.println("Please enter a password");
                String password = scanner.nextLine();   
        
                checkPassword(password);
            }
            /**
             * 
             * @param checkPassword the method check password is validating the input from the the user and check if it matches the password requirements
             * @return
             */
            public static boolean checkPassword(String password){
                boolean upperCase = !password.equals(password.toLowerCase()); //check if the input has a lower case letter
                boolean lowerCase = !password.equals(password.toUpperCase()); //check if the input has a CAPITAL case letter
                boolean isAtLeast8 = password.length()>=8;                    //check if the input is greater than 8 characters
                boolean hasSpecial = !password.matches("[A-Za-z0-9]*");       // check if the input has a special characters
                boolean hasNumber = !password.matches(".*\\d+.*");            //check if the input contains a digit
                if(!isAtLeast8){
                    System.out.println("Your Password is not big enough\n please enter a password with minimun of 8 characters");
                    return true;
                }else if(!upperCase){
                    System.out.println("Password must contain at least one UPPERCASE letter");
                    return true;
                }else if(!lowerCase){
                    System.out.println("Password must contain at least one lower case letter");
                    return true;
                }else if(!hasSpecial){
                    System.out.println("Password must contain a special character");
                    return true;
                }else if(hasNumber){
                    System.out.println("Password must contain at least one number");
                    return true;
                }else{
                    System.out.println("Your password: "+password+", sucessfully match the requirements");
                    return true;
                }
        
            }
        }
        

        【讨论】:

          【解决方案8】:

          这已经很老了,@SinkingPoint 已经在上面给出了很好的答案。现在,有了 Java 8 中可用的函数式惯用语,我们可以再给它一个转折点。你会有两个 lambda:

          Function<String, Boolean> hasLowerCase = s -> s.chars().filter(c -> Character.isLowerCase(c)).count() > 0;
          Function<String, Boolean> hasUpperCase = s -> s.chars().filter(c -> Character.isUpperCase(c)).count() > 0;
          

          然后在代码中我们可以像这样检查密码规则:

          if (!hasUppercase.apply(password)) System.out.println("Must have an uppercase Character");
          if (!hasLowercase.apply(password)) System.out.println("Must have a lowercase Character");
          

          关于其他检查:

          Function<String,Boolean> isAtLeast8 = s -> s.length() >= 8; //Checks for at least 8 characters
          Function<String,Boolean> hasSpecial   = s -> !s.matches("[A-Za-z0-9 ]*");//Checks at least one char is not alpha numeric
          Function<String,Boolean> noConditions = s -> !(s.contains("AND") || s.contains("NOT"));//Check that it doesn't contain AND or NOT
          

          在某些情况下,创建 lambda 是否会在交流意图方面增加价值是有争议的,但 lambda 的好处在于它们是功能性的。

          【讨论】:

          • 好主意。但是,.count() 贯穿整个字符串。所以这更快:boolean hasUpperCase = password.chars().anyMatch(Character::isUpperCase);,恕我直言,可读性也很强。
          【解决方案9】:
          function TellFirstCharacterType(inputString){
              var firstCharacter = inputString[0];
              if(isNaN(firstCharacter)){
                  if(firstCharacter == firstCharacter.toUpperCase()){
                      return "It's a uppercase character";
                  }
                  else{
                      return "It's a lowercase character";
                  }
              }
              else{
                  return "It's a Number";
              }
          }
          

          【讨论】:

          • 请在您的代码中提供一些解释,以便以后的用户可以更轻松地遵循您的想法/代码。
          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 2011-01-16
          • 1970-01-01
          • 2011-12-11
          • 1970-01-01
          • 2021-01-06
          • 1970-01-01
          • 2014-02-12
          相关资源
          最近更新 更多