Überprüfung der Groß-/Kleinschreibung innerhalb einer Zeichenfolge in Java

Lesezeit: 9 Minuten

Benutzer-Avatar
Jon A

Das Problem, das ich habe, ist, dass ich mein Passwort-Verifizierungsprogramm nicht dazu bringen kann, eine Zeichenfolge zu überprüfen, um sicherzustellen, dass eines der Zeichen in Großbuchstaben und eines in Kleinbuchstaben ist, es wird die gesamte Zeichenfolge auf eines der Zeichen überprüfen other und druckt die Fehlermeldung basierend auf der geprüften Anweisung.

Ich habe diese Seite und das Internet nach einer Antwort durchsucht und bin nicht in der Lage, eine zu finden. Das ist Hausaufgabe.

Unten ist mein aktueller Code.

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();
            }
        }
    }
}

  • Ich kann mir vorstellen, dass Sie sich bewerben möchten alle dieser Beschränkungen auf die Passwörter, und sonst ist if nicht das Konstrukt dafür.

    – Hunter McMillen

    21. April 2013 um 4:19 Uhr


Benutzer-Avatar
Untergangspunkt

Um festzustellen, ob ein String einen Großbuchstaben und einen Kleinbuchstaben enthält, können Sie Folgendes verwenden:

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

Damit können Sie Folgendes überprüfen:

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

Im Wesentlichen funktioniert dies, indem überprüft wird, ob der String gleich seinem vollständigen Kleinbuchstaben- oder Großbuchstaben-Äquivalent ist. Wenn dies nicht zutrifft, muss mindestens ein Zeichen groß- oder kleingeschrieben sein.

Ihre anderen Bedingungen können auf ähnliche Weise erfüllt werden:

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

Mit entsprechenden Fehlermeldungen wie oben.

  • Kleine Bearbeitung: password.length() >= 8 da length = 8 ausreichen sollte. Dies wird meine Lieblingsantwort.

    – Flori

    21. April 2013 um 4:57 Uhr

  • Behoben 🙂 Danke für den Spot.

    – Sinkender Punkt

    21. April 2013 um 4:58 Uhr

  • Und danke für deine. Da ich der Meinung bin, dass dies die akzeptierte Antwort werden sollte, sollten keine Fehler darin enthalten sein. Nicht sicher, ob Ihr Sonderzeichentest korrekt ist … es wird ein Passwort mit unter anderem einem von lassen ~()-_=+ durch, aber diese waren nicht in der Liste der “Sonderzeichen”.

    – Flori

    21. April 2013 um 5:07 Uhr


  • Nochmals vielen Dank an Sie beide. Hat mir wirklich geholfen, auf den richtigen Weg zu kommen. Ich genieße das Programmieren, aber ich dachte, ich würde dort für eine Sekunde den Verstand verlieren. (Noch wirklich neu, nur meine 5. Programmierwoche und sie haben mit Java an meiner Schule angefangen.)

    – Jon A

    21. April 2013 um 5:28 Uhr

  • Hoffe du bleibst dabei. Viel Glück für die Zukunft 😀

    – Sinkender Punkt

    21. April 2013 um 5:31 Uhr

Benutzer-Avatar
Floris

Eine Schleife wie diese:

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
            }

Hat einen offensichtlichen logischen Fehler: Sie geben es ein, wenn das erste Zeichen kein Kleinbuchstabe ist, und testen Sie dann, ob das zweite Zeichen kein Kleinbuchstabe ist. An diesem Punkt werfen Sie einen Fehler.

Stattdessen sollten Sie so etwas tun (kein vollständiger Code, nur ein Beispiel):

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
}

Natürlich enthielt das von Ihnen bereitgestellte Code-Snippet neben der fehlerhaften Logik keinen Code zum Testen der anderen Bedingungen, die Ihre “Hilfe” -Option ausgedruckt hat. Wie in einer der anderen Antworten erwähnt, können Sie die Verwendung regulärer Ausdrücke in Betracht ziehen, um den Prozess der Suche nach all diesen Dingen zu beschleunigen. Zum Beispiel,

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

In Code:

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

Es ist möglich, diese Dinge auf clevere Weise zu kombinieren – aber besonders wenn Sie ein Regex-Neuling sind, ist es viel besser, ein bisschen “langsam und mühsam” zu sein und Code zu bekommen, der beim ersten Mal funktioniert (und Sie werden es können herauszufinden, was Sie in sechs Monaten getan haben).

  • Vielen Dank für Ihre schnelle Antwort. Das macht absolut Sinn. Ich bin den falschen Weg eingeschlagen, habe es eine Stunde lang angestarrt und darüber nachgedacht, wie ich es ändern könnte.

    – Jon A

    21. April 2013 um 4:32 Uhr

  • Dies ist zwar viel länger als nötig und prüft nur die ersten 8 Zeichen des Passworts.

    – Sinkender Punkt

    21. April 2013 um 4:38 Uhr


  • @Quirliom – Voraussetzung ist, dass das Passwort laut “Hilfe” -Text acht Zeichen lang ist. Nicht 9, nicht 10. Da steht "\nMust contain 8 characters." Vielleicht habe ich das zu wörtlich genommen. Ich werde entsprechend aktualisieren.

    – Flori

    21. April 2013 um 4:43 Uhr


  • Die Passwortlänge war mein eigener Fehler bei der Ausarbeitung des Programms, ließ “At Least” einfach genug ändern, um password.length zu ändern, um alle Zeichen innerhalb der Zeichenfolge zu überprüfen.

    – Jon A

    21. April 2013 um 4:50 Uhr

  • Auch ein kurzer Punkt, Ihre Überprüfung auf eine Nummer wird sich über ein ungültiges Escape-Zeichen beschweren, Sie müssen dem \ entkommen 🙂

    – Sinkender Punkt

    21. April 2013 um 5:03 Uhr

Benutzer-Avatar
Bohemien

Obwohl dieser Code für einen Anfänger wahrscheinlich unverständlich ist, kann er in einer Zeile mit einem Regex mit positivem und negativem Look-Ahead ausgeführt werden:

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

  • „Enthält weder NOT noch AND, hat eines dieser Sonderzeichen !@#$%^&*, enthält eine Zahl. Sind alle diese Bedingungen getestet? Ich betrachte mich nicht als Neuling, aber ich sehe es nicht.

    – Flori

    21. April 2013 um 4:47 Uhr

  • @Floris Die Frage fragt nach der Behauptung, dass die Zeichenfolge mindestens 1 oberen und mindestens 1 unteren Pflegebuchstaben enthält. Genau das macht mein Code. Mir ist jetzt aufgefallen, dass der Code (nur) aus einer Zahl und einem Sonderzeichen besteht. Antwort bearbeitet, um dies zu berücksichtigen.

    – Böhmisch

    21. April 2013 um 6:08 Uhr


  • +1 für Großartigkeit und Dichte. Ich brauchte eine Weile, um mich davon zu überzeugen, dass die Lookaheads sicher so verkettet werden könnten – ich denke, der Schlüssel ist der .* in jedem von ihnen. Ich lerne immernoch…

    – Flori

    21. April 2013 um 6:28 Uhr

  • Ich habe den Begriff “Dichte” noch nie so verwendet gesehen … Ich mag es! Normalerweise verwende ich “Kürze”, aber es klingt ein bisschen “weich”. „Density“ klingt positiv und cool. Danke – du hast mein Leben verändert 🙂

    – Böhmisch

    21. April 2013 um 6:38 Uhr

  • Das einzige Problem ist, wie Sie dem Endbenutzer mitteilen, welcher Aspekt seines Passworts falsch ist? Dieser Ansatz wird nur Ja oder Nein sagen.

    – Zapnologica

    9. Februar 2016 um 3:19 Uhr

Benutzer-Avatar
Kaffee_fan

Dies ist ziemlich alt und @SinkingPoint hat oben bereits eine großartige Antwort gegeben. Jetzt, mit funktionalen Redewendungen, die in Java 8 verfügbar sind, könnten wir ihm eine weitere Wendung geben. Sie hätten zwei Lambdas:

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;

Dann könnten wir im Code Passwortregeln wie folgt überprüfen:

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

Zu den anderen Kontrollen:

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

In einigen Fällen lässt sich darüber streiten, ob das Erstellen des Lambdas einen Mehrwert in Bezug auf die Kommunikation der Absicht bringt, aber das Gute an Lambdas ist, dass sie funktional sind.

Ich habe die Antwort von @Quirliom oben in Funktionen gestrafft, die verwendet werden können:

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;
}

Benutzer-Avatar
Rahul Vaswani

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";
    }
}

Benutzer-Avatar
Thomas

Ein kurzer Blick durch die Dokumentation zur Syntax für reguläre Ausdrücke sollte Möglichkeiten aufzeigen, um festzustellen, ob es irgendwann einen Klein-/Großbuchstaben enthält.

1019800cookie-checkÜberprüfung der Groß-/Kleinschreibung innerhalb einer Zeichenfolge in Java

This website is using cookies to improve the user-friendliness. You agree by using the website further.

Privacy policy