1. Información general
En este tutorial rápido, ilustraremos cómo podemos verificar si una cadena contiene al menos uno de cada uno de los siguientes: letra mayúscula, letra minúscula, dígito o carácter especial en Java .
2. Usar expresiones regulares
Una de las formas de realizar nuestra comprobación es mediante el uso de expresiones regulares. Para familiarizarse con las expresiones regulares, consulte este artículo.
En primer lugar, definamos la expresión regular para cada uno de los grupos de caracteres requeridos. Dado que las expresiones regulares son fijas, no es necesario evaluarlas en cada ejecución, por lo que las compilaremos antes de compararlas :
private static final Pattern[] inputRegexes = new Pattern[4]; static { inputRegexes[0] = Pattern.compile(".*[A-Z].*"); inputRegexes[1] = Pattern.compile(".*[a-z].*"); inputRegexes[2] = Pattern.compile(".*\\d.*"); inputRegexes[3] = Pattern.compile(".*[`[email protected]#$%^&*()\\-_=+\\\\|\\[{\\]};:'\",/?].*"); }
Además, deberíamos crear un método simple que usaremos para probar si nuestro String cumple las condiciones:
private static boolean isMatchingRegex(String input) { boolean inputMatches = true; for (Pattern inputRegex : inputRegexes) { if (!inputRegex.matcher(input).matches()) { inputMatches = false; } } return inputMatches; }
2.1. Expresión regular única
El ejemplo anterior es bastante legible y nos permite usar solo algunos de los patrones fácilmente si es necesario. Pero, en un caso en el que solo nos preocupemos por cumplir con todas las condiciones, es mucho más eficiente usar una sola expresión regular.
De esa manera, no necesitaríamos un bloque estático para inicializar y compilar todas nuestras expresiones múltiples. Además, no habría necesidad de iterar sobre todos ellos y encontrar qué coincidencias y cuáles no.
Todo lo que tenemos que hacer es declarar nuestra expresión regular:
String regex = "^(?=.*?\\p{Lu})(?=.*?\\p{Ll})(?=.*?\\d)" + "(?=.*?[`[email protected]#$%^&*()\\-_=+\\\\|\\[{\\]};:'\",/?]).*$";
Y luego compílelo y compárelo:
@Test public void givenSingleRegex_whenMatchingCorrectString_thenMatches() { String validInput = "Ab3;"; assertTrue(Pattern.compile(regex).matcher(validInput).matches()); }
Hay algunas cosas que debemos señalar con respecto a nuestra expresión regular.
Primero, hemos utilizado una búsqueda anticipada positiva ( ? = X ) para cada grupo de caracteres . Eso significa que esperamos que X se encuentre después del comienzo de la Cadena (marcado con ^ ) para que coincida, pero no queremos ir al final de X , sino que queremos quedarnos al comienzo de la línea .
Otra cosa a tener en cuenta es que esta vez no usamos [AZ] o [az] para grupos de letras, sino \ p {Lu} y \ p {Ll} en su lugar. Estos coincidirán con cualquier tipo de letra (en nuestro caso, mayúsculas y minúsculas respectivamente) de cualquier idioma, no solo inglés.
3. Usando Core Java
Veamos ahora cómo podemos realizar la misma verificación si no queremos usar expresiones regulares. Aprovecharemos las clases Character y String y sus métodos para verificar si todos los caracteres requeridos están presentes en nuestra String :
private static boolean checkString(String input) { String specialChars = "~`[email protected]#$%^&*()-_=+\\|[{]};:'\",/?"; char currentCharacter; boolean numberPresent = false; boolean upperCasePresent = false; boolean lowerCasePresent = false; boolean specialCharacterPresent = false; for (int i = 0; i < input.length(); i++) { currentCharacter = input.charAt(i); if (Character.isDigit(currentCharacter)) { numberPresent = true; } else if (Character.isUpperCase(currentCharacter)) { upperCasePresent = true; } else if (Character.isLowerCase(currentCharacter)) { lowerCasePresent = true; } else if (specialChars.contains(String.valueOf(currentCharacter))) { specialCharacterPresent = true; } } return numberPresent && upperCasePresent && lowerCasePresent && specialCharacterPresent; }
Debemos señalar algunas cosas aquí. La idea básica es iterar a través de nuestra Cadena y verificar si sus caracteres son de los tipos requeridos. Al usar la clase Character , podemos verificar fácilmente si un determinado carácter es un dígito, un carácter en mayúsculas o minúsculas.
Desafortunadamente, no existe un método similar que nos diga si estamos tratando con uno de los caracteres especiales. Entonces, significa que debemos adoptar otro enfoque.
Hemos creado una cadena que contiene todos los caracteres especiales que necesitamos y luego comprobamos si contiene nuestro carácter específico.
4. Conclusión
En este artículo rápido, mostramos cómo verificar si una cadena contiene los caracteres requeridos. En el primer escenario, usamos expresiones regulares mientras que en el segundo aprovechamos las clases centrales de Java .
Como de costumbre, el código fuente completo se puede encontrar en GitHub.