idipous
idipous

Reputation: 2910

String contains at least one digit

I am trying to see whether a string contains at least a digit or a lowercase or an uppercase.

I have written something like this:

      int combinations = 0;
      string pass = "!!!AAabas1";

      if (pass.matches("[0-9]")) {
          combinations = combinations + 10;
      }

      if (pass.matches("[a-z]")) {
          combinations =combinations + 26;
      }

      if (pass.matches("[A-Z]")) {
          combinations =combinations + 26;
      }

However I don't understand why I cannot get combinations to go to 36. They just remain at 0. What am I doing wrong?

Upvotes: 8

Views: 20089

Answers (6)

Flimtix
Flimtix

Reputation: 398

If you don't want to or are not allowed to use a regex you can also use the following method:

public static boolean containsNumber(String value) {
    for (int i = 0; i < value.length(); i++) {
        if (Character.isDigit(value.charAt(i)))
            return true;
    }
    return false;
}

It goes through the string until it finds a number. If no number was found, then false is returned. However, I suspect that for longer strings the regex variant has better performance.

Upvotes: 0

CooL AndroDev
CooL AndroDev

Reputation: 51

String str_rno = "CooL8";

boolean Flag = false;

String[] parts = str_rno.split(""); 

for (int i = 0; i < str_rno.length(); i++) {

    String part1 = parts[i + 1];      

    if (Character.isDigit(str_rno.charAt(i))) {
        System.out.println(" " + i + " " + part1 + " digit");
        Flag = true;
    } else {
        System.out.println(" " + i + " " + part1 + " char ");
    }

}


if(Flag==true){
    Toast.makeText(getApplicationContext(),"String contain 1 digit",Toast.LENGTH_SHORT).show();
}

if(Flag==flase){
    Toast.makeText(getApplicationContext(),"String not contain 1 digit",Toast.LENGTH_SHORT).show();
}

Upvotes: 1

hoipolloi
hoipolloi

Reputation: 8044

Here's my attempt. Note, this uses unicode categories for validation so is non-latin language friendly.

import java.util.regex.Pattern;

public class PasswordValidator {

    public static void main(String[] args) {
        final PasswordValidator passwordValidator = new PasswordValidator();
        for (String password : new String[] { "abc", "abc123", "ABC123", "abc123ABC", "!!!AAabas1", "гшщз",
                "гшщзЧСМИ22" }) {
            System.out.printf("Password '%s' is %s%n", password, passwordValidator.isValidPassword(password) ? "ok"
                    : "INVALID");
        }
    }
    private static final Pattern LOWER_CASE = Pattern.compile("\\p{Lu}");
    private static final Pattern UPPER_CASE = Pattern.compile("\\p{Ll}");
    private static final Pattern DECIMAL_DIGIT = Pattern.compile("\\p{Nd}");

    /**
     * Determine if a password is valid.
     * 
     * <p>
     * A password is considered valid if it contains:
     * <ul>
     * <li>At least one lower-case letter</li>
     * <li>At least one upper-case letter</li>
     * <li>At least one digit</li>
     * </p>
     * 
     * @param password
     *            password to validate
     * @return True if the password is considered valid, otherwise false
     */
    public boolean isValidPassword(final String password) {
        return containsDigit(password) && containsLowerCase(password) && containsUpperCase(password);
    }

    private boolean containsDigit(final String str) {
        return DECIMAL_DIGIT.matcher(str).find();
    }

    private boolean containsUpperCase(final String str) {
        return UPPER_CASE.matcher(str).find();
    }

    private boolean containsLowerCase(final String str) {
        return LOWER_CASE.matcher(str).find();
    }

}

Here's the output:

Password 'abc' is INVALID
Password 'abc123' is INVALID
Password 'ABC123' is INVALID
Password 'abc123ABC' is ok
Password '!!!AAabas1' is ok
Password 'гшщз' is INVALID
Password 'гшщзЧСМИ22' is ok

Upvotes: 4

ColinD
ColinD

Reputation: 110054

While using a regex for this can obviously work, Guava's CharMatcher class might be a bit more appropriate to what you're trying to do:

if (CharMatcher.inRange('0', '9').matchesAnyOf(pass))
  combinations += 10;
if (CharMatcher.inRange('a', 'z').matchesAnyOf(pass))
  combinations += 26;
if (CharMatcher.inRange('A', 'Z').matchesAnyOf(pass))
  combinations += 26;

Upvotes: 1

Hrzio
Hrzio

Reputation: 396

You could use Pattern instead, I think "matches" method looks for the whole string to match the regular expression.

Try the next code:

    int combinations = 0;
    String pass = "!!AAabas1";
    if (Pattern.compile("[0-9]").matcher(pass).find()) {
        combinations = combinations + 10;
    }

    if (Pattern.compile("[a-z]").matcher(pass).find()) {
        combinations = combinations + 26;
    }

    if (Pattern.compile("[A-Z]").matcher(pass).find()) {
        combinations = combinations + 26;
    }

Upvotes: 12

joeslice
joeslice

Reputation: 3454

The problem is that matches tries to match the entire input string.

Instead, try creating a Pattern, then from there create a Matcher, and then use the find method.

The Pattern javadoc should help a great deal.

Upvotes: 3

Related Questions