I have a problem where I need to ensure that the last two digits in a string (called id) are between the numbers of 01 and 40. I thought I had figured it out, however my testing fails when '00' is used - this should fail but it passes.
I know why it is doing this (due to the greater than/less than) but I can't seem to work out how to overcome this problem. Do I need to join characters 10 and 11 together a string then attache further conditional formatting this way?
{
if ((id.charAt(10)<='0'&& id.charAt(11)<= '9')
return true;
}
else {
return false;
}
}
You can use the method described by 'JustAnotherDeveloper' in the comments (see method isBetween2 below) but it means you rely on Integer.parseInt(String) and on the NumberFormatException that may be thrown to define if the 2 characters at index 10 & 11 are numeric or not, which is not really the best solution.
Yous should use regular expressions instead to ensure the two characters are digits (see method isBetween below).
Please not that in the example below, the regular expression pattern will accept any alphanumeric characters for the 10 first characters. You will have to modify the pattern if needed.
public boolean isBetween(String id) {
Pattern p = Pattern.compile("([[a-zA-Z0-9]]{10})([0-9]{2})");
Matcher n = p.matcher(id);
if (n.find()) {
int i = Integer.parseInt(n.group(2));
return i >= 1 && i <= 40;
} else {
return false;
}
}
public boolean isBetween2(String id) {
String s = id.substring(10, 12);
int i;
try {
i = Integer.parseInt(s);
return i >= 1 && i <= 40;
} catch (NumberFormatException e) {
return false;
}
}
Related
I have a task to write a return type method which takes String as an argument and returns boolean. If the String matches with the requirements it returns true else false.
So it should not have any space, and more then 1 '#'and format must be 2>chars#2>chars.2>chars so it should be xyz#xyz.com is true but if any part of it less then 3 it should return to false. I checked so many forums but all i can find regex and we didn't learn anything about it. I could able to do this much but i just couldn't figure out how can i specifically set length of each part and set it as true or false. I'm missing so many and this is all i able to complete;
public static boolean emailAddress(String str) {
if (str.contains(" "))
return false;
boolean flag = true;
if(str3.length()> 11)
for (int i = 0; i < str3.length(); i++) {
for (int j = i + 1; j < str3.length(); j++) {
if (str3.charAt(i) == str3.charAt(j)) {
flag = false;
break;
}
}
if(flag)
return true;
}
return false;
}
This is how I would approach it:
public static boolean isEmailAddress(String str)
{
if(str.trim().equals("")) // Checking if it is an empty string
{
return false;
}
boolean flag = true;
int atIndex = str.indexOf("#"); // Get the index of #
if (atIndex == -1)
{
return false;
}
// Slice your email str and get only the characters before the #
// Check whether the length and the characters are as you want them.
// Do the same thing about the string between # and .
// and then do the same thing about the sliced string after .
}
Check substring() and indexOf().
For anyone who needs it.
This should be one of the Regex to match your requirement:
[a-zA-Z_0-9]{2,}#[a-zA-Z_0-9]{2,}\.[a-zA-Z_0-9]{2,}
[a-zA-Z_0-9] it requires one of the characters, from a-z,A-Z or 0-9
{2,} it requires two or more from one of the characters inside.
A few hints instead of complete solution:
Check if the input string...
has # and . (there could be two or three period's as some domain uses .co.in)
does not have any white spaces (' ')
does not start with special characters ('#', '^')
If possible, do not check for length of each part, as sometimes .in also valid domain.
This question already has answers here:
What's the best way to check if a String represents an integer in Java?
(40 answers)
Closed 9 years ago.
I'm trying to determine if a particular item in an Array of strings is an integer or not.
I am .split(" ")'ing an infix expression in String form, and then trying to split the resultant array into two arrays; one for integers, one for operators, whilst discarding parentheses, and other miscellaneous items. What would be the best way to accomplish this?
I thought I might be able to find a Integer.isInteger(String arg) method or something, but no such luck.
The most naive way would be to iterate over the String and make sure all the elements are valid digits for the given radix. This is about as efficient as it could possibly get, since you must look at each element at least once. I suppose we could micro-optimize it based on the radix, but for all intents and purposes this is as good as you can expect to get.
public static boolean isInteger(String s) {
return isInteger(s,10);
}
public static boolean isInteger(String s, int radix) {
if(s.isEmpty()) return false;
for(int i = 0; i < s.length(); i++) {
if(i == 0 && s.charAt(i) == '-') {
if(s.length() == 1) return false;
else continue;
}
if(Character.digit(s.charAt(i),radix) < 0) return false;
}
return true;
}
Alternatively, you can rely on the Java library to have this. It's not exception based, and will catch just about every error condition you can think of. It will be a little more expensive (you have to create a Scanner object, which in a critically-tight loop you don't want to do. But it generally shouldn't be too much more expensive, so for day-to-day operations it should be pretty reliable.
public static boolean isInteger(String s, int radix) {
Scanner sc = new Scanner(s.trim());
if(!sc.hasNextInt(radix)) return false;
// we know it starts with a valid int, now make sure
// there's nothing left!
sc.nextInt(radix);
return !sc.hasNext();
}
If best practices don't matter to you, or you want to troll the guy who does your code reviews, try this on for size:
public static boolean isInteger(String s) {
try {
Integer.parseInt(s);
} catch(NumberFormatException e) {
return false;
} catch(NullPointerException e) {
return false;
}
// only got here if we didn't return false
return true;
}
It's better to use regular expression like this:
str.matches("-?\\d+");
-? --> negative sign, could have none or one
\\d+ --> one or more digits
It is not good to use NumberFormatException here if you can use if-statement instead.
If you don't want leading zero's, you can just use the regular expression as follow:
str.matches("-?(0|[1-9]\\d*)");
Or you can enlist a little help from our good friends at Apache Commons : StringUtils.isNumeric(String str)
You want to use the Integer.parseInt(String) method.
try{
int num = Integer.parseInt(str);
// is an integer!
} catch (NumberFormatException e) {
// not an integer!
}
Or simply
mystring.matches("\\d+")
though it would return true for numbers larger than an int
As an alternative approach to trying to parse the string and catching NumberFormatException, you could use a regex; e.g.
if (Pattern.compile("-?[0-9]+").matches(str)) {
// its an integer
}
This is likely to be faster, especially if you precompile and reuse the regex.
However, the problem with this approach is that Integer.parseInt(str) will also fail if str represents a number that is outside range of legal int values. While it is possible to craft a regex that only matches integers in the range Integer.MIN_INT to Integer.MAX_INT, it is not a pretty sight. (And I am not going to try it ...)
On the other hand ... it may be acceptable to treat "not an integer" and "integer too large" separately for validation purposes.
You can use Integer.parseInt(str) and catch the NumberFormatException if the string is not a valid integer, in the following fashion (as pointed out by all answers):
static boolean isInt(String s)
{
try
{ int i = Integer.parseInt(s); return true; }
catch(NumberFormatException er)
{ return false; }
}
However, note here that if the evaluated integer overflows, the same exception will be thrown. Your purpose was to find out whether or not, it was a valid integer. So its safer to make your own method to check for validity:
static boolean isInt(String s) // assuming integer is in decimal number system
{
for(int a=0;a<s.length();a++)
{
if(a==0 && s.charAt(a) == '-') continue;
if( !Character.isDigit(s.charAt(a)) ) return false;
}
return true;
}
You can use Integer.parseInt() or Integer.valueOf() to get the integer from the string, and catch the exception if it is not a parsable int. You want to be sure to catch the NumberFormatException it can throw.
It may be helpful to note that valueOf() will return an Integer object, not the primitive int.
public boolean isInt(String str){
return (str.lastIndexOf("-") == 0 && !str.equals("-0")) ? str.substring(1).matches(
"\\d+") : str.matches("\\d+");
}
I have written regex from numbers from 0 to 31. It shall not allow preceding zeros.
[0-2]\\d|/3[0-2]
But it also allows preceding zeros.
01 invalid
02 invalid
Can some tell me how to fix this.
You can use the following regex:
^(?:[0-9]|[12][0-9]|3[01])$
See demo
Your regex - [0-2]\\d|/3[0-2] - contains 2 alternatives: 1) [0-2]\\d matches a digit from 0-2 range first and then any 1 digit (with \\d), and 2) /3[0-2] matches /, then 3 and then 1 digit from 0-2 range. What is important is that without anchors (^ and $) this expression will match substrings in longer strings, and will match 01 in 010.
Since there has been some discussion about shorthand classes, here is a version with the shorthand class and here is also an example with matches() that requires full input to match and thus we do not need explicit anchors:
String pttrn = "(?:\\d|[12]\\d|3[01])";
System.out.println("31".matches(pttrn));
See demo
Note that the backslash should be doubled here.
You can try with the following pattern:
^(?:[12]?[0-9]|3[01])$
Just another non-Regex approach with data validation before attempting to convert a String to int. Here we are validating that the data is at least 1 character that is a digit, or the data is 2 characters that are digits and the first character is not a 0.
public static void main(String[] args) throws Exception {
List<String> data = new ArrayList() {{
add("01"); // Bad
add("1A"); // Bad
add("123"); // Bad
add("31"); // Good
add("-1"); // Bad
add("32"); // Bad
add("0"); // Good
add("15"); // Good
}};
for (String d : data) {
boolean valid = true;
if (d.isEmpty()) {
valid = false;
} else {
char firstChar = d.charAt(0);
if ((d.length() == 1 && Character.isDigit(firstChar)) ||
(d.length() == 2 &&
(Character.isDigit(firstChar) && firstChar != '0' &&
Character.isDigit(d.charAt(1))))) {
int myInt = Integer.parseInt(d);
valid = (0 <= myInt && myInt <= 31);
} else {
valid = false;
}
}
System.out.println(valid ? "Valid" : "Invalid");
}
}
Results:
Invalid
Invalid
Invalid
Valid
Invalid
Invalid
Valid
Valid
Another option:
\\b(?:[12]?\\d|3[12])\\b
Demo
This regex does not use none-capturing group:
^(\d|[12]\d|3[01])$
Explanation:
^ - start of line \d - single digit 0-9 or [12]\d - tens
and twenties or 3[01] - thirty and thirty one $ - line end
Java DEMO
It is harder to maintain code with regex in it: see When you should not use Regular Expressions
In order to make your code more maintainable and easier for other developers to jump into and support, maybe you could consider converting your String to an Integer and then testing the value?
if((!inputString.startsWith("0") && inputString.length() == 2) || inputString.length() == 1){
Integer myInt = Integer.parseInt(inputString);
if( 0 <= myInt && myInt <= 31){
//execute logic...
}
}
you could also easily break this out into a utility method that is very descriptive such as:
private boolean isBetween0And31Inclusive(String inputString){
try{
if((!inputString.startsWith("0") && inputString.length() == 2) || inputString.length() == 1){
Integer myInt = Integer.parseInt(inputString);
if(0 <= myInt && myInt <= 31){
return true;
}
}
return false;
}catch(NumberFormatException exception){
return false;
}
}
This question already has answers here:
How to use regex in String.contains() method in Java
(6 answers)
Closed 8 years ago.
I'm attempting to check if a string contains only
1
0
.
or a combination of these three.
First I had this code:
public static boolean controleSubnetmask(String mask) {
try {
String[] maskArray = mask.split(".");
int[] subnetmask = new int[4];
//array of string to array of int
for (int i = 0; i < maskArray.length; i++) {
subnetmask[i] = Integer.parseInt(maskArray[i]);
}
return true;
} catch (NumberFormatException e) {
return false;
}
}
but that is rather complicated for what it does, and it doesn't check if only 1 and 0 are entered.
So now I have this, but it seems I misunderstood regular expressions because it doesn't work:
public static void controleSubnetmask(String mask) {
mask = "1100.110...11";
String test = "p";
if (mask.contains("[^10\\.]") == true) {
System.out.println("wrong input");
}
if (test.contains("[^10\\.]") == true) {
System.out.println("wrong input");
}
}
I expected a 'wrong input' message on the test String, which didn't appear. So I believe my regex:
[^01\\.]
is wrong, but I really have no clue how to specify it.
Thanks in advance!
String.contains works with Strings NOT with REGEX. use String.matches
instead. As #lazy points out, you could use Pattern and Matcher classes as well.
test.contains("[^10\\.]") == true
All you are doing here is checking whether test contains the String literals [^10\.]
Edit: Clarification convert any valid number encoding from a string to a number
How does one convert a string to a number, say just for integers, for all accepted integer formats, particularly the ones that throw NumberFormatException under Integer.parseInt. For example, the code
...
int i = 0xff;
System.out.println(i);
String s = "0xff";
System.out.println( Integer.parseInt(s) );
....
Will throw a NumberFormatException on the fourth line, even though the string is clearly a valid encoding for a hexadecimal integer. We can assume that we already know that the encoding is a valid number, say by checking it against a regex. It would be nice to also check for overflow (like Integer.parseInt does), but it would be okay if that has to be done as a separate step.
I could loop through every digit and manually calculate the composite, but that would pretty difficult. Is there a better way?
EDIT: a lot of people are answering this for hexidecimal, which is great, but not completely what I was asking (it's my fault, I used hexidecimal as the example). I'm wondering if there's a way to decode all valid java numbers. Long.decode is definitely great for just catching hex, but it fails on
222222L
which is a perfectly valid long. Do I have to catch for every different number format separately? I'm assuming you've used a regex to tell what category of number it is, i.e, distinguish floats, integers, etc.
You could do
System.out.println(Integer.decode(s));
You need to specify the base of the number you are trying to parse:
Integer.parseInt(s,16);
This will fail if you have that "0x" starting it off so you could just add a check:
if (s.startsWith("0x")) {
s = s.substring(2);
}
Integer.parseInt(s,16);
EDIT
In response to the information that this was not a hex specific question I would recommend writing your own method to parse out all the numbers formats you like and build in on top of Integer.decode which can save you from having to handle a couple of cases.
I would say use regex or create your own methods to validate other formats:
public static int manualDecode(String s) throws NumberFormatException {
// Match against #####L long format
Pattern p = Pattern.compile("\\d+L"); // Matches ########L
Matcher m = p.matcher(s);
if (m.matches()) {
return Integer.decode(s.substring(0,s.length()-1));
}
// Match against that weird underscore format
p = Pattern.compile("(\\d{1,3})_((\\d{3})_)*?(\\d{3})"); // Matches ###_###_###_###_###
m = p.matcher(s);
if (m.matches()) {
String reformattedString = "";
char c;
for (int i = 0; i < s.length(); i++) {
c = s.charAt(i);
if ( c >= '0' && c <= '9') {
reformattedString += c;
}
}
return Integer.decode(reformattedString);
}
// Add as many more as you wish
throw new NumberFormatException();
}
public int parseIntExtended(String s) {
try {
return Integer.decode(s);
} catch (NumberFormatException e) {
return manualDecode(s);
}
}
Integer.decode should do the trick:
public class a{
public static void main(String[] args){
String s="0xff";
System.out.println(Integer.decode(s));
}
}
You can try using BigInteger also but sill you have to remove 0x first or replace x from 0
int val = new BigInteger("ff", 16).intValue(); // output 255