I am a beginner in both, Java and regular expressions. I want to get a name as an input, by which I mean that only names that have English alphabets A-Z, case insensitive and spaces.
I am using a Scanner class to get my input but my code doesn't work. It looks like:
Scanner sc= new Scanner(System.in);
String n;
while(!sc.hasNext("^[a-zA-Z ]*$"))
{
System.out.println("That's not a name!");
sc.nextLine();
}
n = sc.next();
I checked my regular expression on the website regex101.com and found out that it works fine.
For example, If I input it my name, Akshay Arora , the regex site says it is okay but my program prints
That's not a name
That's not a name
Same line is printed twice and it again asks me for input. Where am I going wrong?
Two parts are wrong:
$ and ^ anchors are considered in the context of entire input, not in the context of the next token. It will never match, unless the input has a single line that matches the pattern in its entirety.
You use default delimiters, which include spaces; therefore, Scanner will never return a token with a space in it.
Here is how you can fix this:
Scanner sc = new Scanner(System.in);
sc.useDelimiter("\n");
String n;
while(!sc.hasNext("[a-zA-Z ]+"))
{
System.out.println("That's not a name!");
sc.nextLine();
}
n = sc.next();
Demo.
Here its sample program related to regex.
public class Program {
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String inputName = sc.next();
String regex = "^[a-zA-Z ]*$";
// Compile this pattern.
Pattern pattern = Pattern.compile(regex);
// See if this String matches.
Matcher m = pattern.matcher(inputName);
if (m.matches()) {
System.out.println("Valid Name");
} else
System.out.println("Invalid Name");
}
}
Hope this will help you
Related
I am learning Java day 1 and I have a very simple code.
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
while(input.hasNext()) {
String word = input.next();
System.out.println(word);
}
}
After I input any sentence, the while loop seems to not terminate.
How would I need to change this so that the I could break out of the loop when the sentence is all read?
The hasNext() method always checks if the Scanner has another token in its input. A Scanner breaks its input into tokens using a delimiter pattern that matches whitespace by default.
Whitespace includes not only the space character, but also tab space (\t), line feed (\n), and more other characters
hasNext() checks the input and returns true if it has another non-whitespace character.
Your approach is correct if you want to take input from the console continuously. However, if you just want to have single user input(i.e a sentence or list of words) it is better to read the whole input and then split it accordingly.
eg:-
String str = input.nextLine();
for(String s : str.split(" ")){
System.out.println(s);
}
Well, a simple workaround for this would be to stop whenever you find a stop or any set of strings you would like!
Scanner input = new Scanner(System.in);
while (input.hasNext()) {
String word = input.next();
if (word.equals("stop")) {
break;
}
System.out.println(word);
}
input.close();
System.out.println("THE END!");
I'm supposed to write a program that takes in a string representing an integer as input, and outputs yes if every character is a digit 0-9.
I have gone back through my chapters reading and gone through Google, but I'm still having trouble. I know my code is a mess but I am lost. I may have bits and pieces correct or be wrong all together but this is what I have.
import java.util.Scanner;
public class LabProgram {
public static void main(String[] args) {
Scanner scnr = new Scanner(System.in);
String userString;
// Add more variables as needed
userString = scnr.next();
boolean check1 = Character.isDigit(userString);
while (check1 = True) {
System.out.println ("Yes");
}
System.out.println ("No");
Where did I go wrong?
As pointed out by people in comments, there are some mistakes in your code. Character.isDigit won't work with String. What you need to use is Integer.parseInt(...). You can put it in a try catch block; Print yes if parsing is successful and print No if exception is thrown:
userString = scnr.next();
try {
int parsedValue = Integer.parseInt(userString);
// Do something with parsedValue
System.out.println("Yes");
} catch (NumberFormatException numberFormatException) {
System.out.println("No");
}
You could use regular expressions for that:
import java.util.regex.Matcher;
import java.util.regex.Pattern;
// your input, can also be from a scanner
String input = "1234567890";
// regex pattern to match a string that consists only of numbers and is also not empty
String regex = "^[0-9]+$";
// to match negative numbers as well: "^[\\-]?[0-9]+$"
// create a pattern object
Pattern pattern = Pattern.compile(regex);
// create a matcher object
Matcher matcher = pattern.matcher(input);
// check if the input matches
if (matcher.find()) {
System.out.println("It's a number, yay!");
};
How does the regex work:
^ matches the beginning of the input to make sure there is nothing before the number characters
[0-9]+ tells it to match the range 0-9 one or more times (+), which also makes sure that an empty string does not match
$ matches the end of the string to make sure there is no non-numbers after the match
If you want to match negative numbers as well, there is an additional part of the regex: [\\-]? this matches one minus sign if there is on or none if there is no sign (?)
https://www.tutorialspoint.com/java/java_regular_expressions.htm
It's also possible the way you tried it:
// open a scanner
Scanner scanner = new Scanner(System.in);
// read user input from the scanner
String input = scanner.next();
// assume it is a number until we find a non-digit character below
String isNumber = true;
// loop over each character of the user input
for (char character : input) {
// check if the character is not a digit
if (!Character.isDigit(character)) {
System.out.println("NOT a number: ", character);
// set the is number variable to false
isNumber = false;
// break the loop, because it cannot be a number because we already found a non-digit
break;
};
};
System.out.println("Is it a number? ", isNumber);
String getname(){
Scanner input = new Scanner(System.in);
String name;
System.out.println("Enter your name:");
name= input.next();
String name_pattern = "^[A-Za-z]+(\\s[A-Za-z]+)$";//this regex isnt validating Ben Smith
Pattern pattern = Pattern.compile(name_pattern);
Matcher regexmatcher = pattern.matcher(name);
if(!regexmatcher.matches()){
System.out.println("Name format not correct");
}
return name;
}
I also need to take the input again and again until the correct format is entered. How do i do that? My current regex prints "Name format not correct" when I input "Ben Smith" though it should not print that because Ben Smith is a valid input!
input.next returns the next token from the input rather than the next line. You may set another delimiter in Scanner to return lines but the most custom way is to use
name= input.nextLine();
The Scanner's next() method returns only the next word, in your case "Ben". Replace that with nextLine() to get the whole name.
Scanner input = new Scanner(System.in);
String name;
System.out.println("Enter your name:");
name = input.nextLine();
With that your regular expression matches "Ben Smith".
^[A-Za-z ]+$ is enough.
private final static Pattern NAME_VALIDATOR = Pattern.compile("^[A-Za-z ]+$");
[...]
System.out.println(NAME_VALIDATOR.matcher("Ben Smith").matches());
Note that the Pattern is always the same, so you can just create it once instead of creating it every time you enter the method.
Also note that this will not validate names with ', e.g. O'Brian, neither foreign names, e.g. Mätthaus. Consider using \p{L} instead.
As a comment points out:
"As far as I understand they want only two words with a space
inbetween to be valid"
Then the regex would be "^[A-Za-z]+ [A-Za-z]+$" instead.
How to catch integer if the user must input String only, no integer and Symbols included to the input? Help me sir for my beginner's report.
import java.util.*;
public class NameOfStudent {
public static void main(String[] args) {
Scanner input = new Scanner(System.in);
String name = "";
System.out.print("Please enter your name: ");
name = input.nextLine(); // How to express error if the Strin contains
//integer or Symbol?...
name = name.toLowerCase();
switch(name)
{
case "cj": System.out.print("Hi CJ!");
break;
case "maria": System.out.print("Hi Maria!");
break;
}
}
}
Use this regular expression.
Check if a String contains number/symbols etc..
boolean result = false;
Pattern pattern = Pattern.compile("^[a-zA-Z]+$");
Matcher matcher = pattern.matcher("fgdfgfGHGHKJ68"); // Your String should come here
if(matcher.find())
result = true;// There is only Alphabets in your input string
else{
result = false;// your string Contains some number/special char etc..
}
Throwing custom exceptions
Throwing custom exceptions in java
Working of a try-catch
try{
if(!matcher.find()){ // If string contains any number/symbols etc...
throw new Exception("Not a perfect String");
}
//This will not be executed if exception occurs
System.out.println("This will not be executed if exception occurs");
}catch(Exception e){
System.out.println(e.toString());
}
I just given a overview, how try-catch works. But you should not use a general "Exception" ever. always use your customized exception for your own exceptions.
Once you have the String in your hand, e.g. name you can apply a regexp to it as follows.
String name = "your string";
if(name .matches(".*\\d.*")){
System.out.println("'"+name +"' contains digit");
} else{
System.out.println("'"+name +"' does not contain a digit");
}
Adapt the logic checks to your needs.
Please be aware that a string can contain numeric character, and it's still a string:
String str = "123";
I think what you meant in your question is "How to enforce alphabetical user input, no numeric or symbol", which can be easily done using regular expression
Pattern pattern = Pattern.compile("^[a-zA-Z]+$"); // will not match empty string
Matcher matcher = pattern.matcher(str);
bool isAlphabetOnly = matcher.find();
Use Regex which is a sequence of characters that forms a search pattern:
Pattern pattern = Pattern.compile("^[a-zA-Z]*$");
Matcher matcher = pattern.matcher("ABCD");
System.out.println("Input String matches regex - "+matcher.find());
Explanation:
^ start of string
A-Z Anything from 'A' to 'Z', meaning A, B, C, ... Z
a-z Anything from 'a' to 'z', meaning a, b, c, ... z
* matches zero or more occurrences of the character in a row
$ end of string
If you also want to check for empty string then replace * with +
If you want to do it without regex then:
public boolean isAlpha(String name)
{
char[] chars = name.toCharArray();
for (char c : chars)
{
if(!Character.isLetter(c))
{
return false;
}
}
return true;
}
You can change your code as follows.
Scanner input=new Scanner(System.in);
System.out.print("Please enter your name: ");
String name = input.nextLine();
Pattern p=Pattern.compile("^[a-zA-Z]*$");// This will consider your
input String or not
Matcher m=p.matcher(name);
if(m.find()){
// your implementation for String.
} else {
System.out.println("Name should not contains numbers or symbols ");
}
Follow this link more about Regex. And test some regex by your self from here.
In Java you formulate what the String is allowed to contain in a regular expression. Then you check if the String contains the allowed sequence - and only the allowed sequence.
Your code looks like this. I've added a do-while-loop to it:
Scanner input = new Scanner(System.in);
String name = "";
do { // get input and check for correctness. If not correct, retry
System.out.print("Please enter your name: ");
name = input.nextLine(); // How to express error if the String contains
//integer or Symbol?...
name = name.toLowerCase();
} while(!name.matches("^[a-z][a-z ]*[a-z]?$"));
// The above regexp allows only non-empty a-z and space, e.g. "anna maria"
// It does not allow extra chars at beginning or end and must begin and end with a-z
switch(name)
{
case "cj": System.out.print("Hi CJ!");
break;
case "maria": System.out.print("Hi Maria!");
break;
}
Now you can change the regular expression, e.g. to allow names with asian character sets. Take a look here how to handle predefined character sets. I was once checking any text for words in any language (and any part of the UTF-8 character set) and ended up with a regular expression like this to find the words in a text: "(\\p{L}|\\p{M})+"
if we want to check that two different user enter same email id while registration.....
public User updateUsereMail(UserDTO updateUser) throws IllegalArgumentException {
System.out.println(updateUser.getId());
User existedUser = userRepository.findOneById(updateUser.getId());
Optional<User> user = userRepository.findOneByEmail(updateUser.getEmail());
if (!user.isPresent()) {
existedUser.setEmail(updateUser.getEmail());
userRepository.save(existedUser);
} else {
throw EmailException("Already exists");
}
return existedUser;
}
Scanner s = new Scanner(System.in);
String name;
System.out.println("enter your name => ");
name = s.next();
try{
if(!name.matches("^[a-zA-Z]+$")){
throw new Exception("is wrong input!");
}else{
System.out.println("perfect!");
}
}catch(Exception e){
System.out.println(e.toString());
}
umm..try storing the values in an array..for each single value , use isLetter() and isDigit() ..then construct a new string with that array
use try catch here and see !
i am not used to Pattern class ,use that if thats' simpler
Input, via a question, the report owner’s first name as a string.
Need a regular expression to check, conditionally, to make sure the first name doesn’t contain any numeric characters, numbers between 0 – 9. If it does you must remove it. The first name can not contain any white space either.
do
{
System.out.println("Please enter your FIRST name:");
firstName = keyboard.next();
firstName= firstName.toUpperCase();
}
while( !firstName.matches("^/s^[a-zA-Z]+$/s"));
System.out.println("Thanks " + firstName);
Output
p
Please enter your FIRST name:
p p
Please enter your FIRST name:
Please enter your FIRST name:
You've got your regex muddled up. Try this:
while(!firstName.matches("^[^\\d\\s]+$"));
The regex "^[^\\d\\s]+$" means "non digits or whitespace, and at least one character"
If you want to eliminate digits, just force:
\D*
In your matcher
As you have firstname in uppercase and matches method matches the whole input,
[A-Z]+ is sufficient.
while( !firstName.matches("[A-Z]+"));
or
while( !firstName.matches("\\p{Lu}+"));
Try this one: ^[a-zA-Z,.'-]+$. :D
Also, if you want to try out your regular expressions, rubular.com is a great place for that :D
You used Scanner#next, instead of Scanner#nextLine.
From Scanner#next JavaDoc:
Finds and returns the next complete token from this scanner. A
complete token is preceded and followed by input that matches the
delimiter pattern.
I believe one such delimiter is \s+ :D
import java.util.Scanner;
public class FirstNameParser {
public static void main(String[] args) {
Scanner keyboard = new Scanner(System.in);
String firstName = null;
do {
System.out.print("Please enter your FIRST name: ");
firstName = keyboard.nextLine();
firstName = firstName.toUpperCase();
}
while (!firstName.matches("^[a-zA-Z,.'-]+$"));
System.out.println("Thanks " + firstName);
}
}
Try
firstName = firstName.replaceAll("[\\d\\s]", "").toUpperCase();
You can try this. Created it using Rubular.com. The
Pattern nameRequirment = Pattern.compile("^((?!.[\\d\\s]).)*$");
while (!nameRequirement.matcher(myString).matches()){
//... prompt for new name
}