I am a beginner programmer (first post here!) and I cannot figure out how to create an error message with a "do while" loop. If given input that's not in the alphabet it is supposed to display the error message until given an input with only letters and then move on the to rest of the program. My code seems to loop forever even if given correct input. Any suggestions are greatly appreciated! :)
do {
input = JOptionPane.showInputDialog("What is your name?");
if (input.contains("[a-zA-Z]"))
name = input;
else
System.out.println("Please enter a valid name containing: ‘a-z’ or ‘A-Z’ lower or upper case");
} while (!input.contains("[a-zA-Z]"));
You can show user an error popup so he knows something is wrong with his/her input.
In else statement where you are Printing message just do
JOptionPane.showMessageDialog(frame,
"Please enter a valid name containing: ‘a-z’ or ‘A-Z’ lower or upper case.",
"Input error",
JOptionPane.ERROR_MESSAGE);
return;
For more information
You use the wrong method to validate your regex. .contains() expects a char sequence. That is not what you want.
You should instead use the .matches() method.
String input = "";
do{
input = JOptionPane.showInputDialog("What is your name?");
if (input.matches("[a-zA-Z]+")) // Replacing the contains()
name = input;
else
System.out.println
("Please enter a valid name containing: ‘a-z’ or ‘A-Z’ lower or upper case");
}while (!input.matches("[a-zA-Z]+")); //Once again replacing contains()
input.contains("[a-zA-Z]") checks if input contains the text [a-zA-Z].
You can use the matches method.
input.matches("[a-zA-z]+")
Also, you should use [a-zA-z]+ as the pattern, since you are trying to match one or more alphabets.
The problem is related to how you check for the given input.
String input;
String name = "";
do {
input = JOptionPane.showInputDialog("What is your name?");
if (input.matches("[a-zA-Z]+")) {
name = input;
} else {
System.out.println("Please enter a valid name containing: ‘a-z’ or ‘A-Z’ lower or upper case");
}
} while (!input.matches("[a-zA-Z]+"));
using the matches function of string can help you achieve what you want
String.contains() method matches a set of character sequence.
What you've specified is a regular expression, hence, you should be using String.matches() or the Pattern class to perform the check.
It should be something like this using the Pattern class.
Pattern p = Pattern.compile("[a-zA-Z]+");
Matcher m = p.matcher(input);
if(m.matches){
//Do something
}
Refer to this documentation for more details
Related
EDIT: I figured it out! I got rid of the try-catch block because it just didn't work the way I wanted it to. The code below is my final one. Thank you to everyone who responded to this question.
I am trying to code a to-do list program. One function of this program is to search for the entries inside the string array. The user should only input a ONE WORD keyword so if the user inputs more than one word or none, a prompt should show telling the user to try again. The code I've written so far is inside a try-catch statement. Using next() scanner only takes the first word and disregards the rest when inputting a multiple-word keyword, instead of producing an Exception. Here is my code for it:
case 2:
String searchKeyword;
int success = 0;
while(success==0) {
System.out.print(">> Enter 1 keyword: ");
searchKeyword = sc.nextLine();
String splitSearchKeyword[] = searchKeyword.split(" ");
if (splitSearchKeyword.length == 1) {
if(Quinones_Exer2.searchToDoList(searchKeyword, todoList)==-1) {
System.out.println(">> No item found with that keyword!");
System.out.println();
}
else {
System.out.println(">> Found one item!");
System.out.println("("+(Quinones_Exer2.searchToDoList(searchKeyword, todoList)+1)+")"+" "+todoList[Quinones_Exer2.searchToDoList(searchKeyword, todoList)]);
System.out.println();
}
success++;
}
else {
System.out.println(">> Please input a single word keyword!");
System.out.println();
}
}
break;
}```
Use Scanner.nextLine() then split the supplied string. If the length of array is greater than 1 or the supplied string is empty then issue an invalid entry message and have the User enter the string over again:
while(tries2 == 0) {
searchKeyword = "";
while (searchKeyword.isEmpty()) {
System.out.println("Enter 1 keyword: ");
searchKeyword = sc.nextLine().trim();
if (searchKeyword.isEmpty() || searchKeyword.split("\\s+").length > 1) {
System.out.println("Invalid Entry! {" + searchKeyword
+ "You must supply a single Key Word!");
searchKeyword = "";
}
}
tries2++;
// ... The rest of your code ...
}
From the docs of Scanner.next():
Finds and returns the next complete token from this scanner. A complete token is preceded and followed by input that matches the delimiter pattern.
You would need to call next() again to get the the rest of the input.
Much simpler would be to use Scanner.nextLine() to get entire line and then use String.split() with whatever delimiter you are using to get an array of all inputted keywords.
Edit: Scanner.next(pattern) may do what you are looking for. It throws InputMismatchException if the input does not match provided pattern(regex). Example:
scanner.next("^[a-zA-Z]+$")
This requires the entire line to consist of lower and/or upper case letters and nothing else.
This is the code I have in a setName() method which I want to only accept letters (not digits)
playerName = "";
if (playerName.isDigit)
{System.out.println("Please enter letters only");
}
I am getting an error message which says "illegal parenthesised expression.
String type doesn't have isDigit property. Use the following code to check if your variable contains digits.
if (playerName.matches(".*\\d+.*")) {
System.out.println("Please enter letters only");
}
This code will work for you :
public static void setName ( String playerName ){
if (playerName.matches(".*\\d.*") || playerName.isEmpty()) {
System.out.println("Please enter letters only");
} else {
//Your code here
}
}
You can use Lambda expression to check whether the input string contains only character or not. In your setName() method, do the following
playerName="abcd"; //Take playerName from user input or as method argument
if(playerName==null || playerName.equals("") || !playerName.chars().allMatch(Character::isLetter))
System.out.println("Please enter letters only");
else{
//Do your work if someone enters name containing only letters.
}
There's no isDigit method in String.class in Java, but there're lots of ways to do it.
Take a look: https://mkyong.com/java/java-how-to-check-if-a-string-is-numeric/
I'm creating a program that prints user details, first the user inputs their details and then the program correctly formats the details and prints them inside a formatted box. I want the program to read strings and see if the users have entered invalid characters. For example the code below requests for the users first name:
// this code below is used to find the largest string in my program, ignore if this wont interfere
String fname = scan.nextLine(); //main scan point.
//below is used to calculate largest string inputted by the user.
int input = 0;
int fnamelength1 = fname.length();
input = fnamelength1;
int longest = 0;
if(input > longest)
longest = input;
If at this point the user enters #~~NAME~~# as their name, the program currently allows that... I want to make the program read what the user has inputted and print a message if their input isn't correct for example contains invalid symbols.
EDIT:
I'm considering anything other than characters in the alphabet as invalid... any numbers or symbols would therefore be invalid.
VALID:
ABCDEFGHIJKLMNOPQRSTUVWXYZ
abcdefghijklmnopqrstuvwxyz
Also valid:
' - .
This can be done using regular expressions with the String.matches method. Here you define a pattern and if the string matches your pattern then it can be considered valid:
String fname;
Scanner scan = new Scanner(System.in);
boolean invalidInput;
do{
System.out.println("Enter a valid name");
fname = scan.nextLine();
invalidInput = fname.matches("[^a-zA-Z'-]]");
if(invalidInput){
System.out.println("That's not a valid name");
}
}while (invalidInput);
System.out.println("Name: " + fname);
EDIT
With String.matches we can't make a global search of invalid characters (what we want in this case). So is better using Matcher.find for this:
String fname;
Scanner scan = new Scanner(System.in);
boolean invalidInput;
Pattern pattern = Pattern.compile("[^a-zA-Z'\\-\\s]");
do{
System.out.println("Enter a valid name");
fname = scan.nextLine();
invalidInput = pattern.matcher(fname).find();
if(invalidInput){
System.out.println("That's not a valid name");
}
}while (invalidInput);
System.out.println("Name: " + fname);
This time the pattern will validate any invalid character anywhere in the string.
One approach would be to use regular expressions, along with the String.matches() method.
As an example:
String fname;
... some code to get fname ...
boolean valid = fname.matches("[a-zA-Z]+");
valid should be true if and only if fname is a String containing alphabetic characters, and not empty.
If empty strings are also valid, then:
boolean valid = fname.matches("[a-zA-Z]*");
Look up the Java class Pattern for other variations.
I am trying to perform user input on textbox to check whether they had enter any number or special character in the textbox for their username. I check several resource at online also not able to find out what is my problem inside my code. it's showing me four error message
1) error: 'else' without 'if'
else if(tf3.getText().isEmpty())
2.) error: ';' expected
if(!(Pattern.matches("^[a-zA-Z]$")),tf3.getText())
3.) error: variable declaration not allowed here
if(!(Pattern.matches("^[a-zA-Z]$")),tf3.getText())
4.) error: ';' expected
if(!(Pattern.matches("^[a-zA-Z]$")),tf3.getText())
Here is my full program for my whole program
if(e.getSource()== btn2)
{
if(!(Pattern.matches("^[a-zA-Z]$")),tf3.getText())
{
JOptionPane.showMessageDialog(null,"Please enter a valid name");
}
else if(tf3.getText().isEmpty())
{
JOptionPane.showMessageDialog(null,"Check your name");
}
else if(tf2.getText().isEmpty())
{
JOptionPane.showMessageDialog(null,"Check your id");
}
else if(cmb1.getSelectedIndex()== 0)
{
JOptionPane.showMessageDialog(null,"Check your year");
}
else if(cmb2.getSelectedIndex()== 0)
{
JOptionPane.showMessageDialog(null,"Check your major");
}
else if(cmb3.getSelectedIndex() == 0)
{
JOptionPane.showMessageDialog(null,"Check your selection");
}
else
{
String name = tf3.getText();
String id = tf2.getText();
String job = String.valueOf(cmb1.getSelectedIndex());
String country = String.valueOf(cmb2.getSelectedIndex());
String software = String.valueOf(cmb3.getSelectedIndex());
runCC(software,id,name,job,country);
}
}
Parentheses:
if(!(Pattern.matches("^[a-zA-Z]$")),tf3.getText())
should look like:
if(!Pattern.matches("^[a-zA-Z]$", tf3.getText()))
At least if i got what you meant.
Change
if(!(Pattern.matches("^[a-zA-Z]$")),tf3.getText())
to
if (! Pattern.matches("^[a-zA-Z]$", tf3.getText()))
Ok, since I'm unable to understand what your comments under my answer mean, (not only because i'm drunk!), I'll provide a 'step by step' whats-goin-on:
Pattern class provides a static method: Pattern#matches
It takes two arguments:
First - a string with a regular expression you want to test your string with
Second - a string to test that regex with.
So, whenever you are calling method:
Pattern.matches(regex, string)
You're asking, whether:
"string" matches regular expression "regex"
So in your code you want to say:
"Ok, i want to know, if the text inside tx3 field contains only characters, that are between a-z or between A-Z.
So your regex is: "any sequence of characters, that are between a-z or between A-Z.
That corresponds to
^[a-zA-Z]+$
Now, you call the method that will check, whether your strings matches that regex:
Pattern.matches("%[a-zA-Z]+$", tx3.getText())
That method returns boolean: true, if it matches, or false otherwise.
I don't think anyone will be able to put this more straight-forward.
So far I have been able to censor "cat", "dog" and "llama". Now I just need to make the exception of "Dogmatic" but cannot figure it out for the life of me. Below I have attached what I have so far. Please any suggestions will help really.
/* take userinput and determine if it contains profanity
* if userinput contains profanity, it will be filtered
* and a new sentence will be generated with the word censored
*/
keyboard = new Scanner(System.in);
System.out.println("Welcome to the Star Bulletin Board!");
System.out.println("Generate your first post below!");
String userInput = keyboard.nextLine();
userInput = userInput.toLowerCase();
if (userInput.indexOf("cat") != 15){
System.out.println("Your post contains profanity.");
System.out.println("I have altered your post to appear as: ");
System.out.println(userInput.replaceAll("cat", "***"));
}
else
System.out.println(userInput);
if (userInput.indexOf("dog") != -1){
System.out.println("Your post contains profanity.");
System.out.println("I have altered your post to appear as: ");
System.out.println(userInput.replaceAll("dog", "***"));
}
if (userInput.indexOf("llama")!= -1){
System.out.println("Your post contains profanity.");
System.out.println("I have altered your post to appear as: ");
System.out.println(userInput.replaceAll("llama", "*****"));
}
You can use a word boundary \\b. Word boundaries match the edges of a word, like spaces or punctuation.
if (userInput.matches(".*\\bdog\\b.*")) {
userInput = userInput.replaceAll("\\bdog\\b", "***");
}
This will censor "Don't be a llama." but it won't censor "Don't be dogmatic."
userInput.matches(".*\\bdog\\b.*") is a slightly better condition than indexOf/contains because it has the same match as the replacement. indexOf/contains would still show the message despite not censoring anything. .* matches any character (except typically new lines), optionally.
Note: this is still not a very effective way to filter profanity. See http://blog.codinghorror.com/obscenity-filters-bad-idea-or-incredibly-intercoursing-bad-idea/.
Use word boundaries. Take a look at the following code; it will print true for all cases except the last one:
String a = "what you there";
String b = "yes what there";
String c = "yes there what";
String d = "whatabout this";
System.out.println(Pattern.compile("\\bwhat\\b").matcher(a).find());
System.out.println(Pattern.compile("\\bwhat\\b").matcher(b).find());
System.out.println(Pattern.compile("\\bwhat\\b").matcher(c).find());
System.out.println(Pattern.compile("\\bwhat\\b").matcher(d).find());
You can combine all your bad words into a single regex like so:
Pattern filter = Pattern.compile("\\b(cat|llama|dog)\\b");
This is fine for simple cases, but for a more robust solution you probably want to use a library. Take a look at this question for more information.