Converting charAt check 'containing A-Z' to 'not containing A-Z' - java

I would like to check if a String input contains characters other than alphabets. Below is my current code:
if ((name.charAt(i) >= 'a' && name.charAt(i) <= 'z') ||
((name.charAt(i) >= 'A' && name.charAt(i) <= 'Z')))
How can I change the code such that it functions as check if name.charAt(i) "is not equals to A to Z OR a to z?

Just negate your condition :
if (!((name.charAt(i) >= 'a' && name.charAt(i) <= 'z') || ((name.charAt(i) >= 'A' && name.charAt(i) <= 'Z'))))

String str = "1234";
if(!str.matches("[a-zA-Z]+")){
System.out.println("not contains alphabets");
}else{
System.out.println("contains alphabets");
}

I'll demonstrate a systematic approach to this which can help you in other similar situations. First, to improve readability, extract the char to a local var.
char ch = name.charAt(i);
if (ch >= 'a' && ch <= 'z' || ch >= 'A' && ch <= 'Z') ...
Now you can work with this in terms of DeMorgan's laws. To make things easier, I'll declare some helper boolean vars for each part:
boolean a = ch >= 'a',
z = ch <= 'z',
A = ch >= 'A',
Z = ch <= 'Z';
So, we have your original expression as
(a && z) || (A && Z)
We want the negative of that expression:
!(a && z || A && Z)
Let's clean it up. Apply
to get
!(a && z) && !(A && Z)
Then apply
to the inner expressions:
(!a || !z) && (!A || !Z)
Now substitute the original expresions back in, negating <= into >, >= into <:
(ch < 'a' || ch > 'z') && (ch < 'A' || ch > 'Z')
this is the negated expression you are looking for, cleaned up of any explicit negations.

Instead of comparing characters for upper & lowercase, use Character.isLetter(char c) method as it checks for both the cases.
char[] chars = name.toCharArray();
boolean isAlphabet = true;
for (char c : chars) {
if (!Character.isLetter(c)) {
//if character is not A-Z or a-z
isAlphabet = false;
}
}

Related

Validating String While Loop java No Regex

Basically I'm trying to have a few while loops check specific indices within a string. The first loop that validates the length of the refNum works fine. When it gets to the bigger set of while loops it just skips it and I'm not sure why, any feed back would be greatly appreciated.
package testing_code;
import java.util.Scanner;
/**
*
* #author A.Con
*/
public class Testing_Code
{
public static void main(String[] args)
{
Scanner userInput = new Scanner (System.in);
String refNum;
System.out.println("Enter refNum: example - WE123A");
refNum = userInput.next();
int rnLength = refNum.length();
while(rnLength < 6 || rnLength > 6)
{
System.out.println("Invalid reference number. Try again.\n ");
System.out.println("Please enter reference No.: ");
refNum = userInput.next();
rnLength = refNum.length();
}
while(!(refNum.charAt(0) >= 'A') && !(refNum.charAt(0) <= 'Z') && !(refNum.charAt(1) >= 'A') && !(refNum.charAt(1) <= 'Z'))
{
while(!(refNum.charAt(2) >= '0') && !(refNum.charAt(2) <= '9') && !(refNum.charAt(3) >= '0') && !(refNum.charAt(3) <= '9'))
{
while(!(refNum.charAt(4) >= '0') && !(refNum.charAt(4) <= '9') && !(refNum.charAt(5) >= 'A') && !(refNum.charAt(5) <= 'Z'))
{
System.out.println("Invalid reference number. Try again.\n ");
System.out.println("Please enter reference No.: ");
refNum = userInput.next();
}
}
}
Your while conditions are all wrong. !(refNum.charAt(0) >= 'A') && !(refNum.charAt(0) <= 'Z') for instance checks if a character is lower than A and higher than Z, which is impossible; you should be using or instead.
As a matter of fact, there are a lot of ways you can improve this. Here's my version
public class Testing_Code
{
static boolean inRange(char c, char first, char last) {
return (c >= first) && (c <= last);
}
public static void main(String[] args)
{
Scanner userInput = new Scanner (System.in);
String refNum;
System.out.println("Enter refNum: example - WE123A");
refNum = userInput.next();
while(refnum.length() != 6
|| !inRange(refnum.charAt(0), 'A', 'Z')
|| !inRange(refnum.charAt(1), 'A', 'Z')
|| !inRange(refnum.charAt(2), '0', '9')
|| !inRange(refnum.charAt(3), '0', '9')
|| !inRange(refnum.charAt(4), '0', '9')
|| !inRange(refnum.charAt(5), 'A', 'Z'))
{
System.out.println("Invalid reference number. Try again.\n ");
System.out.println("Please enter reference No.: ");
refNum = userInput.next();
rnLength = refNum.length();
}
}
}
First !(A >= B) is equivalent to (A < B). So !(refNum.charAt(0) >= 'A') && !(refNum.charAt(0) <= 'Z') is equivalent to (refNum.charAt(0) < 'A') && (refNum.charAt(0) > 'Z').
If you look at the ASCII table, you will see that "less than A and greater than Z" are mutually exclusive conditions. They will never both be true at the same time, so the while loop ends up simplifying to while(false)
Your condition while(!refNum.charAt(0) >= 'A') && !(refNum.charAt(0) <= 'Z')) is always false, as a char can't be less than 'A' and greater than 'Z' at same time. Use a || instead of && and you are good to go.
I will recommend using
Character.isLetter(refNum.charAt(0)) // returns true if the passed character is a letter
Character.isDigit(refNum.charAt(0)) // returns true, if the passed character is a digit.
Much simpler & easy to read.

Java: Left-hand side of an argument must be a variable charAt error

I am replacing all vowels in a String with a char using a for loop.
public String replaceVowel(String text, char letter)
{
char ch;
for(int i = 0; i<text.length(); i++)
{
ch = text.charAt(i);
if(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' || ch == 'y')
{
ch = letter;
}
text.charAt(i) = ch;
}
return text;
}
The code trips on an error on line:
text.charAt(i) = ch;
In this line I am attempting to initialize the char at the loop's location of the string. However the line produces the error:
The left-hand side of an assignment must be a variable
Any help is appreciated!
As oppsed to C++, Java method call never return a variable "reference" (like C++ reference) so you can never assign a method call result.
Also Java string is immutable, which means you cannot change individual characters in a string without creating a new string. See this post Replace a character at a specific index in a string? on this topic.
charAt(index) returns the character in that index. It cannot be used for assigning values.
Something like this would work:
char ch;
String text = "hailey";
char letter = 't';
char[] textAsChar = text.toCharArray();
for(int i = 0; i<text.length(); i++)
{
ch = text.charAt(i);
if(ch == 'a' || ch == 'e' || ch == 'i' || ch == 'o' || ch == 'u' || ch == 'y')
{
ch = letter;
}
textAsChar[i] = ch;
}
System.out.println(String.valueOf(textAsChar));

Read input from user and ignore the spaces between words, converting letters to telephone numbers

I've been trying to figure out how to ignore the blank space/digits/letters by using the character.isDigit & character.isLetter method when the users enters a String.. Can you guys please advise me?
When I tried the input with GETLOAN (Without the space) it works well...
But when I enter a space between e..g. Get Loan, the program shows an error..
public static void main(String[] args) {
String letters;
char phoneDigit;
Scanner kb = new Scanner(System.in);
System.out.println("Enter letters : ");
letters = kb.next();
for (int i = 0; i < 7; i++) {
phoneDigit = letters.charAt(i);
// Using character.isDigit...
if (Character.isDigit(phoneDigit) == true || Character.isLetter(phoneDigit) == true);
{
if (i == 3) {
System.out.println("-");
} //If
if (phoneDigit >= 'A' && phoneDigit <= 'C'
|| phoneDigit >= 'a' && phoneDigit <= 'c') {
System.out.println("2");
} else if (phoneDigit >= 'D' && phoneDigit <= 'F'
|| phoneDigit >= 'd' && phoneDigit <= 'f') {
System.out.println("3");
} else if (phoneDigit >= 'G' && phoneDigit <= 'I'
|| phoneDigit >= 'g' && phoneDigit <= 'i') {
System.out.println("4");
} else if (phoneDigit >= 'J' && phoneDigit <= 'L'
|| phoneDigit >= 'j' && phoneDigit <= 'l') {
System.out.println("5");
} else if (phoneDigit >= 'M' && phoneDigit <= 'O'
|| phoneDigit >= 'm' && phoneDigit <= 'o') {
System.out.println("6");
} else if (phoneDigit >= 'P' && phoneDigit <= 'S'
|| phoneDigit >= 'p' && phoneDigit <= 's') {
System.out.println("7");
} else if (phoneDigit >= 'T' && phoneDigit <= 'V'
|| phoneDigit >= 't' && phoneDigit <= 'v') {
System.out.println("8");
} else if (phoneDigit >= 'W' && phoneDigit <= 'Z'
|| phoneDigit >= 'W' && phoneDigit <= 'z') {
System.out.println("9");
} // If
} // If
} // For loop
} //PSVM
remove the semicolon(;) from here
if (Character.isDigit(phoneDigit) == true || Character.isLetter(phoneDigit) == true);//semicolon
; means end of statement.This means if conditions ended there.The statements under if will always be executed irrespective of what if returns(true or false) so the rest of statements under {} will simply behave as non static blocks
When I tried the input with GETLOAN (Without the space) it works well... But when I enter a space between e..g. Get Loan, the program shows an error..
You are getting error when you enter space because of the reason I specified above as the statements under if will always be executed
If you enter two words separated by a space, e.g. "get loan", the Scanner produces two output elements, i.e. the invocation of kb.next() just returns "get". A second invocation would return "loan". The Scanner class is not the right class to use for your purpose.
Use something like
BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
System.out.print("Enter String");
String s = br.readLine();
to read from the console.

ASCII character ranges using for loop

How do I cover the range of all letters lowercase a-z & uppercase A-Z using a for loop? Currently I have:
public static boolean isJavaIdentifierStart (char c) {
if (c == 'a') { //how do I cover the range of all lowercase letters with a for loop?
return true;
} if (c=='Z') { //how do I cover all uppercase letters with a for loop?
return true;
} else if (c == '_') {
return true;
} else if (c == '$') {
return true;
} else
return false;
}
}
If would be much easier to test with the >= and <= operators:
if( c >= 'a' && c <= 'z' ) {
// do something
}
You don't actually need to test all of the values in the range, just make sure c falls inside it somewhere. You can do something similar for uppercase letters.
In fact you can simplify your method into a single return statement:
public static boolean isJavaIdentifierStart (char c) {
return (c >= 'a' && c <= 'z') ||
(c >= 'A' && c <= 'Z') ||
(c == '_') ||
(c == '$');
}
However, I don't believe that Java identifiers can start with $, so your method is incorrect.
It's hard to guess what you want, but you could use:
for(char c = 'a'; c < 'z'; c++) {
System.out.println(c);
}
Edit to your comment:
Use this expression: (c >= 'a' && c <= 'Z') and similiar for range-
checking.
This works since char is a 16 bit unsigned integer, and therefore can be use in calculations.

Function to Sanitize HTML Id attribute in Java

I have coded the next function. But surely someone has a more elegant way to perform this task.
/**
*
* HTML 4 Specification
* ID and NAME tokens must begin with a letter ([A-Za-z]) and may be followed by any number
* of letters, digits ([0-9]), hyphens ("-"), underscores ("_"), colons (":"), and periods (".").
* #param s
* #return
*/
public static String sanitizeHTMLIdAttribute(String s) {
String sanitize = "";
if(s!=null) {
for(int i = 0; i < s.length(); i++) {
if(s.charAt(i) == '-' || s.charAt(i) == '_' || s.charAt(i) == ':' ||
s.charAt(i) == '.' || s.charAt(i) == '0' || s.charAt(i) == '1' ||
s.charAt(i) == '2' || s.charAt(i) == '3' || s.charAt(i) == '4' ||
s.charAt(i) == '5' || s.charAt(i) == '6' || s.charAt(i) == '7' ||
s.charAt(i) == '8' || s.charAt(i) == '9' ||
s.charAt(i) == 'a' || s.charAt(i) == 'b' || s.charAt(i) == 'c' ||
s.charAt(i) == 'd' || s.charAt(i) == 'e' || s.charAt(i) == 'f' ||
s.charAt(i) == 'g' || s.charAt(i) == 'h' || s.charAt(i) == 'i' ||
s.charAt(i) == 'j' || s.charAt(i) == 'k' || s.charAt(i) == 'l' ||
s.charAt(i) == 'm' || s.charAt(i) == 'n' || s.charAt(i) == 'o' ||
s.charAt(i) == 'p' || s.charAt(i) == 'q' || s.charAt(i) == 'r' ||
s.charAt(i) == 's' || s.charAt(i) == 't' || s.charAt(i) == 'u' ||
s.charAt(i) == 'w' || s.charAt(i) == 'x' || s.charAt(i) == 'y' ||
s.charAt(i) == 'z' ||
s.charAt(i) == 'A' || s.charAt(i) == 'B' || s.charAt(i) == 'C' ||
s.charAt(i) == 'D' || s.charAt(i) == 'E' || s.charAt(i) == 'F' ||
s.charAt(i) == 'G' || s.charAt(i) == 'H' || s.charAt(i) == 'I' ||
s.charAt(i) == 'J' || s.charAt(i) == 'K' || s.charAt(i) == 'L' ||
s.charAt(i) == 'M' || s.charAt(i) == 'N' || s.charAt(i) == 'O' ||
s.charAt(i) == 'P' || s.charAt(i) == 'Q' || s.charAt(i) == 'R' ||
s.charAt(i) == 'S' || s.charAt(i) == 'T' || s.charAt(i) == 'U' ||
s.charAt(i) == 'W' || s.charAt(i) == 'X' || s.charAt(i) == 'Y' ||
s.charAt(i) == 'Z') {
sanitize += s.charAt(i);
}
}
if(sanitize.length()>0) {
while(sanitize.charAt(0) == '0' || sanitize.charAt(0) == '1' ||
sanitize.charAt(0) == '2' || sanitize.charAt(0) == '3' ||
sanitize.charAt(0) == '4' || sanitize.charAt(0) == '5' ||
sanitize.charAt(0) == '6' || sanitize.charAt(0) == '7' ||
sanitize.charAt(0) == '8' || sanitize.charAt(0) == '9') {
sanitize = sanitize.substring(1, sanitize.length());
}
}
return sanitize;
}
return null;
}
I would do something like this:
/**
*
* HTML 4 Specification ID and NAME tokens must begin with a letter
* ([A-Za-z]) and may be followed by any number of letters, digits ([0-9]),
* hyphens ("-"), underscores ("_"), colons (":"), and periods (".").
*
* #param s
* #return
*/
public static String sanitizeHTMLIdAttribute(String s) {
if (s == null) return null;
StringBuilder sb = new StringBuilder();
int firstLegal = 0;
while (firstLegal < s.length() && !isAZ(s.charAt(firstLegal)))
++firstLegal;
for (int i = firstLegal; i < s.length(); ++i){
final char ch = s.charAt(i);
if (isOkIdInnerChar(ch)) sb.append(ch);
}
return sb.length() == s.length()? s : sb.toString();
}
private static boolean isOkIdInnerChar(char ch) {
return isAZ(ch) || isNum(ch) || isSpecial(ch);
}
private static boolean isSpecial(char ch) {
switch (ch) {
case '-': case '_':
case ':': case '.':
return true;
default:
return false;
}
}
private static boolean isAZ(char ch) {
return ('A' <= ch && ch <= 'Z') || ('a' <= ch && ch <= 'z');
}
private static boolean isNum(char ch) {
return '0' <= ch && ch <= '9';
}
... except that I'd probably prefer to throw an NullPointerException if s == null, and IllegalArgumentException if s contains no legal characters, but that's a matter of preference, of course. Some extra features:
If s is a valid ID, it's returned as-is to save space (fewer string instances floating around) and time (String construction is expensive -- yes, I know allocation is cheap, but there's more going on there than allocation).
I don't use Character.isDigit 'cause it returns true for all Unicode digits, including stuff like "٣"
I don't use Character.isLetter 'cause it returns true for all Unicode letters, including stuff like "å"
You could significantly shorten your code by using Character.isLetterOrDigit(char); e.g.
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (Character.isLetterOrDigit(c) || c == '.' || etc ...) {
}
}
You could do this in conjunction with storing the permitted punctuation characters in a Set; e.g.
private static final Set<Character> ALLOWED =
new HashSet<Character>(Arrays.asList('.', '-', '_', ':'));
for(int i = 0; i < s.length(); i++) {
char c = s.charAt(i);
if (ALLOWED.contains(c)) {
}
}
You might want to check the expressions (regex isn't my forte), but this should drop invalid characters:
private static Pattern INVALID_LEADING = Pattern.compile("^[^a-zA-Z]+");
private static Pattern INVALID = Pattern
.compile("[^\\w\\u002e\\u003a\\u002d\\u005f]+");
private static String sanitize(String id) {
Matcher matcher = INVALID_LEADING.matcher(id);
if (matcher.find()) {
id = matcher.replaceFirst("");
}
Matcher invalid = INVALID.matcher(id);
if (invalid.find()) {
id = invalid.replaceAll("");
}
return id;
}
If you aren't happy with regex, be aware that many of your characters are in contiguous ranges, so can be detected with methods like this:
private static boolean isLatinDigit(char ch) {
return ch >= '0' && ch <= '9';
}

Categories