How to test if a string contains numbers at certain points - java

I have a string with 6 characters in length. The first character must be a
capital letter, and the last 5 characters must be digits.
I need to write
code to return true if the characters that follow after the capital letter
are digits, and false if they are not.
Here is what I have so far, but when
testing the code, I get an error:
public boolean hasValidDigits(String s)
{
if (Character.isDigit(s.charAt(1-5))) {
return true;
} else {
return false;
}
}

Next time please put the error description.
What you need here is Regex which test the string to the pattern.
i.e.:
return s.matches("[A-Z]{1}[0-9]{5}");
[A-Z]{1}[0-9]{5} means: one capital letter, and 5 digits after.

Check str.matches("[A-Z][0-9]{5}");

Related

How do I match non-word characters anywhere in the string?

This is a simple question, but please hear me out - A part of a homework assignment for Java has a password validator method. The requirements are simple - password must be between 6-10 characters, must be made only of digits or letters and has to have at least 2 digits in it to be valid. I made this with if statements and using regex, for some reason I cannot get the non-word character regex to match despite every online regex checker showing this should work and even the jetbrains plugin for regex check shows this should be valid. (I also understand this could be done with a one-liner and none of the if statements but this way is simpler for me.
Example input - MyPass123 should be valid, MyPass123# should match the non-word character and should return "Password must consist only of letters and digits" instead this never happens. I am a beginner in Java so it is most likely I am not doing something right even though it is such a simple problem. Thank you in advance!
Method code below:
public static void passswordCheck(String password)
{
if(password.length()<6 || password.length()>10)
{
System.out.printf("Password needs to be between 6 and 10 characters");
}
else if(password.matches("\\W")) \\This should match when input is MyPass123#
{
System.out.printf("Password must consist only of letters and digits");
}
else if(!password.matches("/(\\d).*(\\d)/"))
{
System.out.printf("Password needs to have at least 2 digits");
}
else
{
System.out.printf("Password is valid");
}
}
You're only matching if the string consists of a single character which is non alphanumeric (= [^a-zA-Z0-9_]).
If you want any string which contains at least one non alphanumeric character: .*?\W.*
String#matches always performs a whole match, i.e. the match needs to span the whole string from the first to the last character. To search for a match anywhere in the string, you need to use the find method of a Matcher object instead:
final Pattern nonWordChar = Pattern.compile("\\W");
if (nonWordChar.matcher(password).find()) {
System.out.printf("Password must consist only of letters and digits");
}
…
You will need to do the same with your other regular expressions.
I have tested the below code. Two options are possible, try using the find method as mentioned by Konrad in one of the comments above or handle it in the regex to match a character anywhere in the string.
\\w{6,10} - Matches only the valid passwords which contains word character(A-Za-z0-9)
.*?\\d{2,}.*? - Looks for 2 or more consecutive digits
I have changed it to use Pattern.matches.
import java.util.regex.*;
public class test {
public static void passswordCheck(String password)
{
if(password.length()<6 || password.length()>10)
{
System.out.println("Password needs to be between 6 and 10 characters");
}
else if(!Pattern.matches("\\w{6,10}",password)) //This should match when input is MyPass123#
{
System.out.println("Password must consist only of letters and digits");
}
else if(!Pattern.matches(".*?\\d{2,}.*?",password))
{
System.out.println("Password needs to have at least 2 digits");
}
else
{
System.out.println("Password is valid");
}
}
public static void main(String[] args)
{
passswordCheck("Mypass2");
}
}
Problems in your code:
You have used \W (i.e. [^\w]) which matches non-word character but note that \w matches not only digits and alphabets but also _ which you do not need in the valid password. Therefore, you need to use \p{Alnum}. Alternatively, you can use [A-Za-z0-9]. Also, in order to consider the whole string, the quantifier + is required.
The pattern, \d.*\d matches the string bounded by two digits which can be at any place (i.e. not just at the beginning and at the end) in the password and therefore, you need to match any place, not the whole string. You can understand it from this example. Thus, String#match will be able to match the whole string only when the digits are placed in the beginning and at the end. Therefore, you need to use Matcher#find instead of String#match. Note that you do not need parenthesis ( ) around \d in your regex pattern. The parenthesis ( ) is used to specify capturing group which you do not need for your requirement.
Given below is a demo code addressing all these issues:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
public class Main {
public static void main(String[] args) {
// Test strings
String[] arr = { "abcdefghjk", "abc1def2gh", "Ab1Cd2EfGh", "Ab1CdEfGhI", "Ab1Cd2E3Gh", "Ab_ed2EFG3" };
for (String s : arr) {
System.out.println("Validating the password, " + s);
passswordCheck(s);
}
}
public static void passswordCheck(String password) {
if (password.length() < 6 || password.length() > 10) {
System.out.println("Password needs to be between 6 and 10 characters.\n");
} else if (!password.matches("\\p{Alnum}+")) {
System.out.println("Password must consist only of letters and digits.\n");
} else {
Pattern pattern = Pattern.compile("\\d.*\\d");
Matcher matcher = pattern.matcher(password);
if (!matcher.find()) {
System.out.println("Password needs to have at least 2 digits.\n");
} else {
System.out.println("Password is valid\n");
}
}
}
}
Output:
Validating the password, abcdefghjk
Password needs to have at least 2 digits.
Validating the password, abc1def2gh
Password is valid
Validating the password, Ab1Cd2EfGh
Password is valid
Validating the password, Ab1CdEfGhI
Password needs to have at least 2 digits.
Validating the password, Ab1Cd2E3Gh
Password is valid
Validating the password, Ab_ed2EFG3
Password must consist only of letters and digits.

Using a recursive method to determine if a word is elf-ish

public static boolean Xish
This method should take in two parameters, in the following order: A String of the word to check and a String made up of the letters to check for. For example, a word is considered elf-ish, if it contains the letters e, l, and f, in any order (“waffle”, “rainleaf”) and a true return of the method would be Xish(“waffle”, ”elf”). If there are multiple occurrences of a letter to check for, it must occur multiple times in the search word. Return true if the word contains all the needed characters and false if it does not contain all the characters.
This is what I have so far, but I am lost how I would recall the method and check to see if there are multiple occurrences (2nd part).
public static boolean Xish(String check, String letters) {
String word = check;
String contains= letters;
if(word.indexOf(contains) >= 0)
return true;
else
return false;
}
Actually, doing this recursively will also take care of the multiple occurrences issue.
First, your own method is not really correct - it looks for the whole letters in the word. That is, if letters is elf, then true will be returned for self, but not for heartfelt, and that's wrong. You are supposed to look for the individual letters, because the order is not important.
For recursion:
If the letters is an empty string - return true. You can say that any word is fine if there are no restrictions.
If the check is an empty string - return false. An empty string does not contain the letters in letters (and we already know that letters is not empty).
Take the first letter in letters. Look for it in check. If it's not there, return false.
If it was there, then call the same method, but pass only what remains of check and letters. For example, if check was selfish and letters was elf, you found that e exists. Return the result of Xish("slfish","lf"). This will take care of the multiple occurrences. You do that by using substring and concatenating the applicable parts.
If multiple occurrences weren't an issue, you could pass the check as-is to the next level of the recursion. But since they matter, we need to remove one letter for each letter requested, to make sure that we don't match the same position again for the next occurrenc.
The title mentions a recursive function so I will propose a recursive solution.
For each character in your check string, compare it against the first character in your letters string.
If the compared characters are equivalent, remove the first character from your letters string and pass both strings back into your function.
If the check string is fully iterated without finding a character in the letters string, return false
If letters is empty at any point, return true
This is a brute force approach, and there are several other ways to accomplish what you are looking for. Maybe think about how you could check every character in your in you check string a single time?
public static boolean Xish(String check, String letters) {
boolean ish = true;
String word = check;
char[] contains= letters.toCharArray();
for(int i = 0; i < contains.length; i++){
if(word.indexOf(contains[i]) < 0){
ish = false;
}else {
StringBuilder sb = new StringBuilder(word);
sb.deleteCharAt(word.indexOf(contains[i]));
word = sb.toString();
// System.out.println(word);
}
}
return ish;
}
This could be one way, but it is not recursive.
Xish("Waffle", "elff") returns true, but
Xish("Waffle", "elfff") returns false.
Not sure whether it solves your question 100 %. But i tried a recursive method. See if this helps.
package com.company;
public class Selfish {
public static void main(String args[]) {
String check = "waffle";
String letters = "elf"; // "eof"
int xishCount = xish(check, letters, 0);
if(letters.length()== xishCount) {
System.out.println("TRUE");
}else{
System.out.println("FALSE");
}
}
static int xish(String check, String letters, int xishCount) {
if(letters.length() < 1) {
return 0;
}
if(check.contains(letters.substring(0, 1))) {
xishCount = 1;
}
return xishCount + xish(check, letters.substring(1, letters.length()), 0);
}
}

checking for specific characters in String using matches()

What im trying to do is reject any string that contains characters outside a-z, 0-9 or _
I tried using the match function below as id seen elsewhere but i cant get it to work correctly. It will either tell me the string is fine when its not, or it will tell me its not fine when it is.
public static Boolean checkc(String word) {
String w = word;
for (int i = 0; i < w.length(); i++) {
if (w.substring(i, i).matches("[A-Za-z0-9_]")) {
return true;
}
}
return false;
}
The logic might be wrong now because I've fiddled with it trying to get it working but to be fair, it wasnt working in the first place. Im checking a few things in the function thats calling this, so i just need to know if it string is fine given the rules.
The end index argument to substring is exclusive, so substring(i, i) always returns a 0 length string. You could fix this by using substring(i, i+1), but there's no reason to use a loop here. You can just use word.matches("[A-Za-z0-9_]+") and check the entire string at once. The regex quantifier + means "one or more". You could also use the quantifier * which means "zero or more", if the method should return true if the string is empty.
Edit: There's also another problem with your loop logic that I just noticed. Your conditional in the loop returns true the first time the condition is met:
for (...) {
if ( /* condition is met */ )
return true;
}
return false;
That logic only requires that the condition be met at least once, and then it returns true, but you probably meant the following:
for (...) {
if (! /* condition is met */ )
return false;
}
return true;
That requires that the condition be met for every character.
Try this:
public static boolean check(String word) {
return word.matches("[^a-zA-Z0-9_]+");
}
this method returns true when word string contains no single character described in the square bracket, ^ regex symbol means same as logical ! (in example !true == false). Plus symbol + after square bracket means that one symbol [] could repeat one or more time.
javadoc link to Pattern class (regex explanations and examples)
Regex101 convenient online regex debug tool
stringToCheck.String.matches("[^0-9a-zA-Z_]")
This will check whether string that needs to be matched contains any digits or alphabets and return a boolean value

How to check if the first four characters of a string are A-G and the last 3 are numeric?

I have been poking around with this and I feel it might be best if the string (AAAA-123 or AAA123) be split up into 2 strings and compared. I can ensure they are all numeric characters but making sure they are in the right format and I dont feel that I must be missing something.
Name = txtfClass.getText();
if((Name.length()==8)&&(Name.matches("[a-gA-G]-\\d{3}"))){
checker(Name);
System.out.println("it works");
}
That code wont work when Name = ABCD-123. What is it that I'm missing? If you are wondering here checker(Name) goes:
public boolean checker(String name){
CourseAbrv = name.substring(0, 4);
System.out.println(CourseAbrv);
return false;
}
It returns nothing
Change your regex to Name.matches("[A-G]{4}-\\d{3}"). [a-gA-G] matches a Single character.
Note : This matches only capital A-G. You can use a-g instead of A-G to match only lowercase.

Java - How to test if a String contains both letters and numbers

I need a regex which will satisfy both conditions.
It should give me true only when a String contains both A-Z and 0-9.
Here's what I've tried:
if PNo[0].matches("^[A-Z0-9]+$")
It does not work.
I suspect that the regex below is slowed down by the look-around, but it should work regardless:
.matches("^(?=.*[A-Z])(?=.*[0-9])[A-Z0-9]+$")
The regex asserts that there is an uppercase alphabetical character (?=.*[A-Z]) somewhere in the string, and asserts that there is a digit (?=.*[0-9]) somewhere in the string, and then it checks whether everything is either alphabetical character or digit.
It easier to write and read if you use two separate regular expressions:
String s = "blah-FOO-test-1-2-3";
String numRegex = ".*[0-9].*";
String alphaRegex = ".*[A-Z].*";
if (s.matches(numRegex) && s.matches(alphaRegex)) {
System.out.println("Valid: " + input);
}
Better yet, write a method:
public boolean isValid(String s) {
String n = ".*[0-9].*";
String a = ".*[A-Z].*";
return s.matches(n) && s.matches(a);
}
A letter may be either before or after the digit, so this expression should work:
(([A-Z].*[0-9])|([0-9].*[A-Z]))
Here is a code example that uses this expression:
Pattern p = Pattern.compile("(([A-Z].*[0-9])|([0-9].*[A-Z]))");
Matcher m = p.matcher("AXD123");
boolean b = m.find();
System.out.println(b);
Here is the regex for you
Basics:
Match in the current line of string: .
Match 0 or any amount of any characters: *
Match anything in the current line: .*
Match any character in the set (range) of characters: [start-end]
Match one of the regex from a group: (regex1|regex2|regex3)
Note that the start and end comes from ASCII order and the start must be before end. For example you can do [0-Z], but not [Z-0]. Here is the ASCII chart for your reference
Check the string against regex
Simply call yourString.matches(theRegexAsString)
Check if string contains letters:
Check if there is a letter: yourString.matches(".*[a-zA-Z].*")
Check if there is a lower cased letter: yourString.matches(".*[a-z].*")
Check if there is a upper cased letter: yourString.matches(".*[A-Z].*")
Check if string contains numbers:
yourString.matches(".*[0-9].*")
Check if string contains both number and letter:
The simplest way is to match twice with letters and numbers
yourString.matches(".*[a-zA-Z].*") && yourString.matches(".*[0-9].*")
If you prefer to match everything all together, the regex will be something like: Match a string which at someplace has a character and then there is a number afterwards in any position, or the other way around. So your regex will be:
yourString.matches(".*([a-zA-Z].*[0-9]|[0-9].*[a-zA-Z]).*")
Extra regex for your reference:
Check if the string stars with letter
yourString.matches("[a-zA-Z].*")
Check if the string ends with number
yourString.matches(".*[0-9]")
This should solve your problem:
^([A-Z]+[0-9][A-Z0-9]*)|([0-9]+[A-Z][A-Z0-9]*)$
But it's unreadable. I would suggest to first check input with "^[A-Z0-9]+$", then check with "[A-Z]" to ensure it contains at least one letter then check with "[0-9]" to ensure it contains at least one digit. This way you can add new restrictions easily and code will remain readable.
What about ([A-Z].*[0-9]+)|([0-9].*[A-Z]+) ?
Try using (([A-Z]+[0-9])|([0-9]+[A-Z])) .It should solve.
use this method:
private boolean isValid(String str)
{
String Regex_combination_of_letters_and_numbers = "^(?=.*[a-zA-Z])(?=.*[0-9])[a-zA-Z0-9]+$";
String Regex_just_letters = "^(?=.*[a-zA-Z])[a-zA-Z]+$";
String Regex_just_numbers = "^(?=.*[0-9])[0-9]+$";
String Regex_just_specialcharachters = "^(?=.*[##$%^&+=])[##$%^&+=]+$";
String Regex_combination_of_letters_and_specialcharachters = "^(?=.*[a-zA-Z])(?=.*[##$%^&+=])[a-zA-Z##$%^&+=]+$";
String Regex_combination_of_numbers_and_specialcharachters = "^(?=.*[0-9])(?=.*[##$%^&+=])[0-9##$%^&+=]+$";
String Regex_combination_of_letters_and_numbers_and_specialcharachters = "^(?=.*[a-zA-Z])(?=.*[0-9])(?=.*[##$%^&+=])[a-zA-Z0-9##$%^&+=]+$";
if(str.matches(Regex_combination_of_letters_and_numbers))
return true;
if(str.matches(Regex_just_letters))
return true;
if(str.matches(Regex_just_numbers))
return true;
if(str.matches(Regex_just_specialcharachters))
return true;
if(str.matches(Regex_combination_of_letters_and_specialcharachters))
return true;
if(str.matches(Regex_combination_of_numbers_and_specialcharachters))
return true;
if(str.matches(Regex_combination_of_letters_and_numbers_and_specialcharachters))
return true;
return false;
}
You can delete some conditions according to your taste

Categories

Resources