Validate a string contains only certain characters in java - java

Ok, what I am trying to do is take a user input in infix notation and translate it to postfix and then evaluate it. I have that already completed.
What I am struggling with, is for the user input I need to validate that it only contains the following: (), 0-9, +, -, *, /, %
Each character will be separated by a space, so here is a potential valid input:
( 3 + 4 ) * 5 / ( 6 - 7 )
I have created an InvalidCharacterException that I wish to throw if the user string contains anything other than those characters.
Here is what an invalid input would look like:
3 - 5 ^ 5
The ^ would be an invalid character and then I would throw new InvalidCharacterException and ask for a new input.
I will also say I have looked at a ton of regex samples, and to be honest I don't understand what they're doing.
EDIT:
Ok, this is what I ended up implementing because I don't really understand anything else. Any advice on a simpler way?
for(int i = 0; i <= infix.length(); i++){
if(infix.charAt(i) == '(' || infix.charAt(i) == ')' || infix.charAt(i) =='+'
|| infix.charAt(i) =='-' ||infix.charAt(i) == '*' ||infix.charAt(i) == '/'
||infix.charAt(i) == '%' ||infix.charAt(i) ==' ' ||infix.charAt(i) == '0'
||infix.charAt(i) == '1' || infix.charAt(i) =='2' || infix.charAt(i) =='3'
||infix.charAt(i) == '4' ||infix.charAt(i) == '5' ||infix.charAt(i) == '6'
||infix.charAt(i) == '7' || infix.charAt(i) =='8' ||infix.charAt(i) == '9'){
}else{
throw new InvalidCharacterException(infix.charAt(i));
}
}
Infix is the variable name of my user input as a StringBuffer.

You can use a Scanner to validate your string:
Scanner scanner = new Scanner(string);
String validationResult = scanner.findInLine("[^0-9()+\\-*\\/%]+");
if (validationResult != null) {
// Invalid character found.
throw new InvalidCharacterException("Invalid character: " + validationResult);
}
The findInLine method returns a String with the characters that match the regex and the regex looks for any character not valid in your validation. The findInLine only returns a non null String when there are any invalid characters in the String.

I would suggest you use a Scanner (for an example) and then loop over each character (in each token) and throw your Exception if your criteria are met (e.g. look at Character.isDigit) or just write your own method to test against acceptable characters (e.g. is char is contained in"()0123456789+-*/%").

In your code this is probably better because it does the same thing.
Btw it probably should be i < infix.length() not <=
for(int i = 0; i < infix.length(); i++){
char x = infix.charAt(i);
if(!(Character.isDigit(x) || x == '/' || x == '*' ||
x == '+'|| x== '-' || x=='%' || x == '\n'))
throw new InvalidCharacterException(x);
/* what you want to do if valid*/
}

Related

Error when trying to get a character in a string replaced [duplicate]

This question already has answers here:
What does a "Cannot find symbol" or "Cannot resolve symbol" error mean?
(18 answers)
How to replace replace vowels with a special character in Java?
(5 answers)
Closed 5 years ago.
For my program I am trying to replace all the vowels in a word with asterisk. I have written the code but keep receiving an error in the line where I am trying to replace the letter. The error I receive is " cannot find symbol" can someone explain to me why I am receiving this error?
for(int index =0; index<=length;index++){
Character vowel = firstName.charAt(index);
if ((vowel == 'A') || (vowel == 'a') || (vowel == 'E') || (vowel == 'e') || (vowel == 'I') || (vowel == 'i')
|| (vowel == 'O') || (vowel == 'o') || (vowel == 'U') || (vowel == 'u')){
vowel = vowel.replace( vowel, '*'); // error received here
}
}
why don't you just do :
firstName = firstName.replace(firstName.charAt(index), '*');
or
firstName = firstName.replace(vowel, '*');
I would prefer a single regular expression to your loop logic, and you might use ?i to ignore case. Basically, match any vowel and replace with an asterisk. Like,
String firstName = "David";
System.out.println(firstName.replaceAll("(?i)[aeiou]", "*"));
Outputs
D*v*d
vowel is of typ Character and does not have a .replace method. Not exactly sure what you want to achive but you might want to replace the char in firstname:
firstname.replace( vowel, '*');

Stack Matching Output Error

I was wondering if I could get some assistance, I'm having issues with this created class the output is incorrect. Any help would be appreciated:
import java.util.*;
public class Comparison {
public static void main(String[] args) {
Stack<Character> stack = new Stack<>();
System.out.print("Please enter arithmetic expression: For example, the expression {25 + (3 – 6) * 8}");
Scanner input = new Scanner(System.in);
{
String capture = input.next();
for (int i = 0; i < capture.length(); i++) {
char p = capture.charAt(i);
if (p == '(' || p == '{' || p == '[' || p == ')' || p == '}' || p == ']') {
stack.push(p);
}
char r = stack.peek();
if (p == '{' && r == '}' || p == '(' && r == ')' || p == '[' && r == ']') {
stack.pop();
System.out.print("Arithmetic Expression: has matched symbols. ");
} else {
System.out.print("Arithmetic Expression: has mismatched symbols. ");
}
}
}
}
}
Output:
Please enter arithmetic expression: For example, the expression {25 + (3 – 6) * 8}
{25 + (3 – 6) * 8}
Arithmetic Expression: has mismatched symbols. Arithmetic Expression: has mismatched symbols. Arithmetic Expression: has mismatched symbols. BUILD SUCCESSFUL (total time: 6 seconds)
Expected Output:
The expected output should be only the symbols in this case the output should read Arithmetic Expression: has matched symbols: (), {} as the code is popping once a match is found. The numeric values are of no concern. But If there are no matches - Arithmetic Expression: has mismatched symbols. (Then symbols).

So I need to find all vowels in a string and replace them using a loop

So I have this and be aware that I only use simple methods such at toString(), charAt. Right now my code is just returning the original string, and I do not know why.
Ok, so I realized that after a few tests, the reason it is returning the original string is because in the nested if statement in the loop, the condition is never true, so it bypasses the if statement. Why is it never true?
System.out.print("Enter in a string: ");
String userInput = scan.nextLine();//string user enters
String vowelChar;//individual character within user's input
for (int i=0; i<userInput.length(); i++){
Character indChar = userInput.charAt(i);
vowelChar = indChar.toString();
if (vowelChar=="a" || vowelChar=="e" || vowelChar=="i" || vowelChar=="o" || vowelChar=="u"){
String beforeText = userInput.substring(0, i-1);//string before vowel
String afterText = userInput.substring(i+1);//string after vowel
userInput=beforeText+"_"+afterText;
}else{
//character is not a vowel
//do nothing
}
}
System.out.print(userInput);
}
}
A few things to consider:
Don't use "==" when comparing Strings, as explained in: Why doesn’t == work on String?
You can compare chars with "==", so you shouldn't need to convert it to a String for the comparison.
The index in your for loop starts at 0, so this statement:
String beforeText = userInput.substring(0, i-1)
will throw a java.lang.StringIndexOutOfBoundsException if there is a vowel at the first index.
You don't need the "else" case if you aren't doing anything inside it.
Although this isn't how I would implement the kind of loop you wanted, here is a solution that works with the least amount of changes to your original code:
System.out.print("Enter in a string: ");
String userInput = scan.nextLine();//string user enters
for (int i = 0; i < userInput.length(); i++) {
Character indChar = userInput.charAt(i);
if (indChar == 'a' || indChar == 'e' || indChar == 'i' || indChar == 'o' || indChar == 'u' ||
indChar == 'A' || indChar == 'E' || indChar == 'I' || indChar == 'O' || indChar == 'U') {
String beforeText = userInput.substring(0, i); //string before vowel
String afterText = userInput.substring(i + 1); //string after vowel
userInput = beforeText + "_" + afterText;
}
}
System.out.print(userInput);
Instead of converting back to String and comparing with == (since we compare the value of Strings via Object#equals), use the char type for your comparison using if/switch. Additionally you should compare in a singular casing so as not to have A and a not match.
char c = Character.toLowerCase(userInput.charAt(i)); //make the character lowercase
switch (c) {
case 'a':
case 'e':
case 'i':
case 'o':
case 'u':
//replace vowel
break;
}
There is no need to convert to a String. Compare characters directly
Character indChar = userInput.charAt(i);
if ((vowelChar == 'a' || vowelChar == 'e' || vowelChar == 'i' || vowelChar=='o' || vowelChar=='u') {
// ...
}
Note the char in single quotes and not double quotes
Change your code like this
if (vowelChar.equals("a") || vowelChar.equals("e") || vowelChar.equals("i") || vowelChar.equals("o") || vowelChar.equals("u")){
Or
if (indChar =='a' || indChar =='e' || indChar =='i' || indChar =='o' || indChar =='u'){
String a = "abcde";
Character indChar = a.charAt(0);
String vowelChar = indChar.toString();
System.out.println("vowelChar Char: " + vowelChar);
System.out.println(vowelChar == "a"); printed false
System.out.println(vowelChar.equals("a")); printed true
So use equals instead of ==

trying to count vowels, consonants and spaces but ignoring other char's

Here is my code, it works fine ( I think) but if I want to enter in a sentence with some other characters such as ". , * : ; "...etc then surely they would be counted as consonants.
Is there a way to shorten this without typing out all the characters that aren't vowels?
Also, I know I could use "ignoreCase()" instead of typing out all the capital versions of the vowels but realised after I typed them and am too stubborn to change :D
public void compute() {
for (int i = 0; i < str.length(); i++) {
if (str.charAt(i) == 'a' || str.charAt(i) == 'e' || str.charAt(i) == 'i' || str.charAt(i) == 'o' || str.charAt(i) == 'u' || str.charAt(i) == 'A'
|| str.charAt(i) == 'E' || str.charAt(i) == 'I' || str.charAt(i) == 'O' || str.charAt(i) == 'U') {
vowels++;
} else if (str.charAt(i) == ' ') {
spaces++;
} else {
cons++;
}
}
}
You can make use of Character.isLetter method to check whether character is a valid letter or some special character. Here is what javadoc says for isLetter method:
public static boolean isLetter(char ch)
Determines if the specified character is a letter. A character is
considered to be a letter if its general category type, provided by
Character.getType(ch), is any of the following:
UPPERCASE_LETTER
LOWERCASE_LETTER
TITLECASE_LETTER
MODIFIER_LETTER
OTHER_LETTER
Not all letters have case. Many characters are letters but are neither
uppercase nor lowercase nor titlecase.
The obvious alternative would be something like this:
String vowels = "aeiou";
and then:
if (vowels.contains(str.substring(i,i+1)){
vowels++;
}
You could do sets of course, but what's the point?

Checking for special characters and spaces

I have a hangman game created in java. I want to create a simple function that will check if the word input has white space and/or special characters.
I've found the functions String.replaceAll(), but I haven't been able to dig up a premade function that returns a boolean value for if there are special charactors and/or white space.
Is there a function out there already? Or at least a simpler way of specifying no white space or special characters other than doing the following?
public void checkWord()
{
boolean flag = false;
for(int i=0;i<wordArray.length;i++)
{
if(wordArray[i] == '1' || wordArray[i] == '2' || wordArray[i] == '3' || wordArray[i] == '4' || wordArray[i] == '5' || wordArray[i] == '6' || wordArray[i] == '7' || wordArray[i] == '8' || wordArray[i] == '9' )
{
flag = true;
}
}
if(flag == true)
{
System.out.println("Invalid characters used in the word");
System.exit(0);
}
}
The function is getting dense, and I've only covered digits. Thoughts?
You can use a simple regular expression:
public boolean isValidWord(String w) {
return w.matches("[A-Za-z]*");
}
Explanation of the regex:
[A-Za-z] - capital or lowercase letter
* - zero or more
More info on regexes: http://www.regular-expressions.info/

Categories

Resources