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.
Related
I can't figure out why this loop does not execute even once:
String s = "1 2\n3 4";
Scanner scanner = new Scanner(s);
while(scanner.hasNext("\\d\\s\\d")) {
System.out.printf("%d %d\n", scanner.nextInt(), scanner.nextInt());
}
To my understanding, "\d\s\d" means digit followed by whitespace followed by another digit - exactly what the input is like, but the loop never executes even once.
My intention is to use Scanner with stdin where I want to assure that input has a sequence of two-digit pairs separated by whitespace, but the code example above is simplified, as I assume I'm doing something wrong with how I use the regex.
Can anyone offer an explanation? Thanks in advance.
The pattern String provided to hasNext(String) is applied after the tokenization of the Scanner.
Returns true if the next token matches the pattern constructed from
the specified string.
By default, that is whitespace. So \\d\\s\\d is applied to the character 1 in your String s. Obviously, that doesn't match.
Based on your comments, I believe you are better off using String#split here:
String s = "1 2\n3 4";
toks = s.split( "\n" );
for (String tok: toks)
System.out.printf("<%s>%n", tok);
Output:
<1 2>
<3 4>
PS: You can use Scanner also by using regex to match your numbers:
String s = "1 2\n3 4";
Scanner scanner = new Scanner(s);
while(scanner.hasNext("\\d+")) {
System.out.printf("<%d %d>%n", scanner.nextInt(), scanner.nextInt());
Output:
<1 2>
<3 4>
Homework question that I've been having a little trouble with...
I need to have a user input string as a product category. If the user inputs more than one word, I need to take only the first word typed.
Stipulation: I cannot use 'if' statements.
Here's what I have so far, but it fails if only one word is typed.
Scanner scan = new Scanner (System.in);
System.out.println ("Enter a noun that classifies the"
+ " type of your product:");
String noun = scan.nextLine();
int n = noun.indexOf(" ");
String inputnoun = noun.substring(0,n);
Use string.split()
Scanner scan = new Scanner (System.in);
System.out.println ("Enter a noun that classifies the"
+ " type of your product:");
String noun = scan.nextLine();
String inputnoun = noun.split(" ")[0];
You can use scan.next() to get only the first word.
The method split(String regex) in the string class will return an array of strings split on the regex string.
String test = "Foo Bar Foo Bar"
String[] array = test.split(" ");
//array is now {Foo, Bar, Foo, Bar}
From there you can figure out how to get the first word.
Next time you are stuck, the Java API pages are very helpful for finding new methods.
You can use String[] array = noun.split("\\s+"), to split between the spaces, and then use array[0] to return the first word.
Instead of manipulating the entire input String, another way is to use the delimiter of the Scanner class:
Scanner scan = new Scanner(System.in);
// Following line is not mandatory as the default matches whitespace
scan.useDelimiter(" ");
System.out.println("Enter a noun that classifies the"
+ " type of your product:");
String noun = scan.next();
System.out.println(noun);
Note that we are using next() instead of nextLine() of the Scanner class.
The user will enter a=(number here). I then want it to cut off the a= and retain the number. It works when I use s.next() but of course it makes me enter it two times which I don't want. With s.nextLine() I enter it once and the delimiter does not work. Why is this?
Scanner s = new Scanner(System.in);
s.useDelimiter("a=");
String n = s.nextLine();
System.out.println(n);
Because nextLine() doesn't care about delimiters. The delimiters only affect Scanner when you tell it to return tokens. nextLine() just returns whatever is left on the current line without caring about tokens.
A delimiter is not the way to go here; the purpose of delimiters is to tell the Scanner what can come between tokens, but you're trying to use it for a purpose it wasn't intended for. Instead:
String n = s.nextLine().replaceFirst("^a=","");
This inputs a line, then strips off a= if it appears at the beginning of the string (i.e. it replaces it with the empty string ""). replaceFirst takes a regular expression, and ^ means that it only matches if the a= is at the beginning of the string. This won't check to make sure the user actually entered a=; if you want to check this, your code will need to be a bit more complex, but the key thing here is that you want to use s.nextLine() to return a String, and then do whatever checking and manipulation you need on that String.
Try with StringTokenizer if Scanner#useDelimiter() is not suitable for your case.
Scanner s = new Scanner(System.in);
String n = s.nextLine();
StringTokenizer tokenizer = new StringTokenizer(n, "a=");
while (tokenizer.hasMoreTokens()) {
System.out.println(tokenizer.nextToken());
}
or try with String#split() method
for (String str : n.split("a=")) {
System.out.println(str);
}
input:
a=123a=546a=78a=9
output:
123
546
78
9
When I type a phrase into the console, only one word appears below the green text while the other words do not appear. Not sure what I am doing wrong here. Any help would be appreciated.
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter a sentence or phrase. It can be anything you want it to be: ");
//ask user for sentence or phrase
String p1 = keyboard.next();
System.out.println(c1); //display user sentence or phrase
next() reads a single word1, use nextLine() to read the entire line.
1 Specifically, 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". The default delimiter is \s+, a continuous string of whitespace characters. You can change this delimiter via useDelimiter.
Change your code to this:
Scanner keyboard = new Scanner(System.in);
System.out.println("Enter a sentence or phrase. It can be anything you want it to be: ");
//ask user for sentence or phrase
String p1 = keyboard.nextLine();
System.out.println(c1); //display user sentence or phrase
The problem is
keyboard.next();
only gets a single word. You need to use:
keyboard.nextLine();
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
}