I am writing a code that takes a person's name and sees if it fits the REGEX criteria. If it does, it follows through a loop and continues on with the code. If the name is not valid, the code will exit. So far I have made it so it can take input and check the names. It is working for all except 2 names. O’Malley, John F. and John O’Malley-Smith. These two names need to be acceptable but the code keeps kicking them out saying they are invalid.
So far I have attempted using
String REGEX = ("^[\\-\\.\\'\\, a-zA-Z ]*$");
This gets me a solid return on all the names except for the 2 mentioned above. I know I have to add somethings to the REGEX code, and have attempted \b boundaries, however have had no luck getting them to work. Any help would be appreciated on what I should add to the REGEX and where to put it inside the code. Here is also the list of valid and invalid names, as well as my code.
Acceptable inputs for name:
Bruce Schneier
Schneier, Bruce
Schneier, Bruce Wayne
O’Malley, John F.
John O’Malley-Smith
Cher
Unacceptable inputs for name:
Ron O’’Henry
Ron O’Henry-Smith-Barnes
L33t Hacker
//alert(“XSS”)//
select * from users;
(All Invalid Names Are Not Accepted At This Time)
public class InputAsker {
public static void main (String[]args) {
Scanner keyboard = new Scanner(System.in);
System.out.print("Please Input Your Name: ");
String myName = keyboard.nextLine();
String REGEX = ("^[\\-\\.\\'\\, a-zA-Z ]*$");
Pattern pattern = Pattern.compile(REGEX);
Matcher matcher = pattern.matcher(myName);
boolean matchfound = false;
while (matcher.find()) {
System.out.println("That's A Great Name! Let's Continue");
matchfound = true;
//loop will continue here
}
if (!matchfound) {
System.out.println("Sorry, Not A Valid Name! Please Try Again!");
}
}
}
Related
This question already has answers here:
Java regular expressions and dollar sign
(5 answers)
Closed 4 years ago.
I have two simple questions about Pattern.
First one is reading the given name(s) and surname. I need to tell whether they contain numbers or punctuation characters. If not, it's a valid name. Whatever I input, the output is
This is not a valid name.
What am I doing wrong?
Scanner input = new Scanner(System.in);
System.out.print("Enter: ");
String name = input.next();
Pattern p = Pattern.compile("[A-Za-z]");
Matcher m = p.matcher(name);
boolean n = m.matches();
if (n == true) {
System.out.println(name);
}
else {
System.out.println("This is not a valid name.");
}
The second question: I read a list of salary amounts that start with a dollar sign $ and followed by a non-negative number, and save the valid salaries into an array. My program can output an array, but it can't distinguish $.
Scanner sc = new Scanner(System.in);
System.out.print("Enter Salary: ");
String salary = sc.nextLine();
Pattern pattern = Pattern.compile("($+)(\\d)");
Matcher matcher = pattern.matcher(salary);
String[] slArray=pattern.split(salary);
System.out.print(Arrays.toString(slArray));
I wouldn't even use a formal matcher for these simple use cases. Java's String#matches() method can just as easily handle this. To check for a valid name using your rules, you could try this:
String name = input.next();
if (name.matches("[A-Za-z]+")) {
System.out.println(name);
}
else {
System.out.println("This is not a valid name.");
}
And to check salary amounts, you could use:
String salary = sc.nextLine();
if (salary.matches("\\$\\d+(?:\\.\\d+)?")) {
System.out.println("Salary is valid.");
}
A note on the second pattern \$\d+(?:\.\d+)?, we need to escape dollar sign, because it is a regex metacharacter. Also, I did not use ^ and $ anchors in any of the two patterns, because String#matches() by default applies the pattern to the entire string.
Edit:
If you have multiple currency amounts in a given line, then split by whitespace to get an array of currency strings:
String input = "$23 $24.50 $25.10";
String[] currencies = input.split("\\s+");
Then, use the above matching logic to check each entry.
Explanation
Your regex pattern is wrong. You are missing the symbol to repeat the pattern.
Currently you have [A-Za-z] which matches only one letter. You can repeat using
* - 0 to infinite repetitions
? - 0 to 1 repetitions
+ - 1 to infinite repetitions
{x, y} - x to y repetitions
So you probably wanted a pattern like [A-Za-z]+. You can use sites like regex101.com to test your regex patterns (it also explains the pattern in detail). See regex101/n6OZGp for an example of your pattern.
Here is a tutorial on the regex repetition symbols.
For the second problem you need to know that $ is a special symbol in regex. It stands for the end of a line. If you want to match the $ symbol instead you need to escape it by adding a backslash:
"\\$\\d+"
Note that you need to add two backslashes because the backslash itself has a special meaning in Java. So you first need to escape the backslash using a backslash so that the string itself contains a backslash:
\$\d+
which then is passed to the regex engine. The same if you want to match a + sign, you need to escape it.
Notes
If you just want to check a given String against a pattern you can use the String#matches method:
String name = "John";
if (name.matches("[A-Za-z]+")) {
// Do something
}
Also note that there are shorthand character classes like \w (word character) which is short for [A-Za-z0-9_].
Code like
if (n == true) { ... }
can be simplified to just
if (n) { ... }
Because n already is a boolean, you don't need to test it against true anymore.
To parse currency values you should consider using already given methods like
NumberFormat format = NumberFormat.getCurrencyInstance();
Number num = format.parse("$5.34");
See the documentation of the class for examples.
I have a scenario where user has to enter its first Name and last name in a single field, so there must be a space between 2 names, and after space there must be atleast a character. I tried to using contains(""), but this method returns true if user just enter a space and does not enter anything after that space.
Kindly guide me a way to achieve this. I have also tried to search Regular Expression but failed to find any.
Here is the regex and a test:
#Test
public void test_firstAndLastName_success() {
Pattern ptrn = Pattern.compile("(\\w+)\\s+(\\w+)");
Matcher matcher = ptrn.matcher("FirstName LastName");
if (matcher.find()) {
Assert.assertEquals("FirstName", matcher.group(1));
Assert.assertEquals("LastName", matcher.group(2));
} else {
Assert.fail();
}
}
The validation is the matcher returning false on find.
If you do not want to permit multiple spaces (\s+) then either remove + (which will still permit for a single tab) or replace it with a space.
You can use code like this:
public static void main(String[] args) throws IOException {
String input = "first last";
if (input.matches("[a-zA-Z]*[\\s]{1}[a-zA-Z].*")) {
String[] name = input.split(" ");
System.out.println(Arrays.toString(name));
} else {
System.out.println("Please input the valid name.");
}
}
It will put first name and last name to array if:
[a-zA-Z]* - input begins with characters;
[\\s]{1} - contains only one space;
[a-zA-Z].* - ends with at least one character.
A simple split using " " will do after trimming the string.
Please check the below code for more understanding :
String[] splitter = null;
String s = "abbsd sdsdf"; // string with 2 words and space
splitter = s.trim().split(" ");
if(splitter.length!=2){
System.out.println("Please enter first or last name");
}
else{
System.out.println("First Name : "+splitter[0]);
System.out.println("Last Name : "+splitter[1]);
}
s = "abc"; //string without space
splitter = s.trim().split(" ");
if(splitter.length!=2){
System.out.println("Please enter first or last name");
}
else{
System.out.println("First Name : "+splitter[0]);
System.out.println("Last Name : "+splitter[1]);
}
Please check with other scenarios with and without space. This should be helpful.
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.
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
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
}