\n
Solution:
\nI was able to solve this by using this following code provided by a comment on this question. All other post are valid as well.
\nWhat I used that worked came from the first comment. Although all the example code provided seems to be valid as well!
\nString text = "abc"; \nString number; \n\nif (Pattern.matches("[a-zA-Z]+", text) == false && text.length() > 2) {\n number = text; \n}\n
\n","author":{"@type":"Person","name":"RedHatcc"},"upvoteCount":264,"answerCount":25,"acceptedAnswer":{"@type":"Answer","text":"If you'll be processing the number as text, then change:
\n\nif (text.contains(\"[a-zA-Z]+\") == false && text.length() > 2){\n
\n\nto:
\n\nif (text.matches(\"[0-9]+\") && text.length() > 2) {\n
\n\nInstead of checking that the string doesn't contain alphabetic characters, check to be sure it contains only numerics.
\n\nIf you actually want to use the numeric value, use Integer.parseInt()
or Double.parseDouble()
as others have explained below.
As a side note, it's generally considered bad practice to compare boolean values to true
or false
. Just use if (condition)
or if (!condition)
.
Reputation: 3136
I have a string that I load throughout my application, and it changes from numbers to letters and such. I have a simple if
statement to see if it contains letters or numbers but, something isn't quite working correctly. Here is a snippet:
String text = "abc";
String number;
if (text.contains("[a-zA-Z]+") == false && text.length() > 2) {
number = text;
}
Although the text
variable does contain letters, the condition returns as true
. The and &&
should eval as both conditions having to be true
in order to process the number = text;
Solution:
I was able to solve this by using this following code provided by a comment on this question. All other post are valid as well.
What I used that worked came from the first comment. Although all the example code provided seems to be valid as well!
String text = "abc";
String number;
if (Pattern.matches("[a-zA-Z]+", text) == false && text.length() > 2) {
number = text;
}
Upvotes: 264
Views: 802714
Reputation:
You can use Regex.Match
if (text.matches("\\d*")&& text.length() > 2) {
System.out.println("number");
}
Or you could use on versions like Integer.parseInt(String)
or better, Long.parseLong(String)
for bigger numbers like for example:
private boolean onlyContainsNumbers(String text) {
try {
Long.parseLong(text);
return true;
} catch (NumberFormatException ex) {
return false;
}
}
And then test with:
if (onlyContainsNumbers(text) && text.length() > 2) {
// do Stuff
}
Upvotes: 4
Reputation: 1220
I got the same problem in my code, and here is a simple function to check if the string value can be converted into an int.
private boolean isOnlyNumber(String zipCode) {
for (int i = 0; i < zipCode.length(); i++) {
if (!Character.isDigit(zipCode.charAt(i)))
return false;
}
return true;
}
hope this helps.
Upvotes: 1
Reputation: 3265
I realize this is an old question, but I consider it still relevant today.
Although the String matching solution is the most elegant one (at least in my opinion), it is far from being performant. So, if you plan to use this method at scale, you might consider alternative implementations.
I wrote a few short classes for comparing the run times of various implementations. For each implementation, I ran 100 million iterations, half with an all-numeric input (so the method returns true
) and half with letters (so the method returns false
) and following are the results of the runs on my machine.
text.matches("\\d*");
Total runtime: 19206 ms
Similar to the String matching solution, but with better running time because pattern compilation is done only once:
PATTERN.matcher(text).matches();
where PATTERN is defined only once as such: final Pattern PATTERN = Pattern.compile("\\d*");
Total runtime: 9193 ms
Less concise than the matching solutions, but faster:
text.isEmpty() || IntStream.range(0, text.length()).allMatch(i -> Character.isDigit(text.charAt(i)));
Total runtime: 5568 ms
Using the same concept as the IntStream solution, but more verbose:
boolean allDigits = true;
if (!text.isEmpty()) {
for (int i = 0; i < text.length(); i++) {
if (!Character.isDigit(text.charAt(i))) {
allDigits = false;
break;
}
}
}
return allDigits;
Total runtime: 235 ms
There is also the commons lang solution which doesn't require you to write any code, but to depend on an external library instead:
StringUtils.isNumeric(text);
Total runtime: 1433 ms
What this test shows is that - leaving aside the external dependency solution - the more elegant the code, the less performant it is, with the most "primitive" solution being also the fastest running one.
That being said, I'm an advocate of clean code, so if you only need to call this method a few times, definitely go for one of the more elegant solutions; in many cases code quality is more important than performance. However, if you know you will be calling it a lot or if it's going to be part of a library, consider going for one of the less elegant but more performant solutions.
Upvotes: 4
Reputation: 3029
In order to simply check whether the string only contains ALPHABETS use the following code:
if (text.matches("[a-zA-Z]+")){
// your operations
}
In order to simply check whether the string only contains NUMBER use the following code:
if (text.matches("[0-9]+")){
// your operations
}
Hope this will help someone!
Upvotes: 28
Reputation: 797
You could use [a-zA-Z]{2,}
as well.
where [a-zA-Z]
checks for alphabets only and {2,}
checks the length, should be greater than 2
Upvotes: 1
Reputation: 191
boolean flag = false;
System.out.print("Enter String : ");
String str = new Scanner(System.in).next();
for (int i = 0; i < str.length(); i++)
{
if (str.length() <= 0)
{
System.out.println("String length Can't be zero.");
return;
}
char ch = str.charAt(i);
int c = ch;
if (c >= 48 && c <= 58)
{
flag = true;
} else
{
flag = false;
break;
}
}
if (flag)
{
System.out.println("input [" + str + "] contains number only.");
} else
System.out.println("input [" + str + "] have some non string values in it.");
Upvotes: 1
Reputation: 5307
A solution with Java 8 streams and lambda
String data = "12345";
boolean isOnlyNumbers = data.chars().allMatch(Character::isDigit);
Upvotes: 10
Reputation: 13302
Here is a sample. Find only the digits in a String and Process formation as needed.
text.replaceAll("\\d(?!$)", "$0 ");
For more info check google Docs https://developer.android.com/reference/java/util/regex/Pattern Where you can use Pattern
Upvotes: 1
Reputation: 11
public class Test{
public static void main(String[] args) {
Scanner sc = new Scanner(System.in);
String str;
boolean status=false;
System.out.println("Enter the String : ");
str = sc.nextLine();
char ch[] = str.toCharArray();
for(int i=0;i<ch.length;i++) {
if(ch[i]=='1'||ch[i]=='2'||ch[i]=='3'||ch[i]=='4'||ch[i]=='5'||ch[i]=='6'||ch[i]=='7'||ch[i]=='8'||ch[i]=='9'||ch[i]=='0') {
ch[i] = 0;
}
}
for(int i=0;i<ch.length;i++) {
if(ch[i] != 0) {
System.out.println("Mixture of letters and Digits");
status = false;
break;
}
else
status = true;
}
if(status == true){
System.out.println("Only Digits are present");
}
}
}
Upvotes: 1
Reputation: 840
Slightly modified version of Adam Bodrogi's:
public class NumericStr {
public static void main(String[] args) {
System.out.println("Matches: "+NumericStr.isNumeric("20")); // Should be true
System.out.println("Matches: "+NumericStr.isNumeric("20,00")); // Should be true
System.out.println("Matches: "+NumericStr.isNumeric("30.01")); // Should be true
System.out.println("Matches: "+NumericStr.isNumeric("30,000.01")); // Should be true
System.out.println("Matches: "+NumericStr.isNumeric("-2980")); // Should be true
System.out.println("Matches: "+NumericStr.isNumeric("$20")); // Should be true
System.out.println("Matches: "+NumericStr.isNumeric("jdl")); // Should be false
System.out.println("Matches: "+NumericStr.isNumeric("2lk0")); // Should be false
}
public static boolean isNumeric(String stringVal) {
if (stringVal.matches("^[\\$]?[-+]?[\\d\\.,]*[\\.,]?\\d+$")) {
return true;
}
return false;
}
}
Had to use this today so just posted my modifications. Includes currency, thousands comma or period notation, and some validations. Does not include other currency notations (euro, cent), verification commas are every third digit.
Upvotes: 1
Reputation: 1645
Here is my code, hope this will help you !
public boolean isDigitOnly(String text){
boolean isDigit = false;
if (text.matches("[0-9]+") && text.length() > 2) {
isDigit = true;
}else {
isDigit = false;
}
return isDigit;
}
Upvotes: 2
Reputation: 101
It is a bad practice to involve any exception throwing/handling into such a typical scenario.
Therefore a parseInt() is not nice, but a regex is an elegant solution for this, but take care of the following:
-fractions
-negative numbers
-decimal separator might differ in contries (e.g. ',' or '.')
-sometimes it is allowed to have a so called thousand separator, like a space or a comma e.g. 12,324,1000.355
To handle all the necessary cases in your application you have to be careful, but this regex covers the typical scenarios (positive/negative and fractional, separated by a dot): ^[-+]?\d*.?\d+$
For testing, I recommend regexr.com.
Upvotes: 1
Reputation: 11479
Working test example
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.lang3.StringUtils;
public class PaserNo {
public static void main(String args[]) {
String text = "gg";
if (!StringUtils.isBlank(text)) {
if (stringContainsNumber(text)) {
int no=Integer.parseInt(text.trim());
System.out.println("inside"+no);
} else {
System.out.println("Outside");
}
}
System.out.println("Done");
}
public static boolean stringContainsNumber(String s) {
Pattern p = Pattern.compile("[0-9]");
Matcher m = p.matcher(s);
return m.find();
}
}
Still your code can be break by "1a" etc so you need to check exception
if (!StringUtils.isBlank(studentNbr)) {
try{
if (isStringContainsNumber(studentNbr)){
_account.setStudentNbr(Integer.parseInt(studentNbr.trim()));
}
}catch(Exception e){
e.printStackTrace();
logger.info("Exception during parse studentNbr"+e.getMessage());
}
}
Method for checking no is string or not
private boolean isStringContainsNumber(String s) {
Pattern p = Pattern.compile("[0-9]");
Matcher m = p.matcher(s);
return m.find();
}
Upvotes: 1
Reputation: 190
Performance-wise parseInt
and such are much worser than other solutions, because at least require exception handling.
I've run jmh tests and have found that iterating over String using charAt
and comparing chars with boundary chars is the fastest way to test if string contains only digits.
Tests compare performance of Character.isDigit
vs Pattern.matcher().matches
vs Long.parseLong
vs checking char values.
These ways can produce different result for non-ascii strings and strings containing +/- signs.
Tests run in Throughput mode (greater is better) with 5 warmup iterations and 5 test iterations.
Note that parseLong
is almost 100 times slower than isDigit
for first test load.
## Test load with 25% valid strings (75% strings contain non-digit symbols)
Benchmark Mode Cnt Score Error Units
testIsDigit thrpt 5 9.275 ± 2.348 ops/s
testPattern thrpt 5 2.135 ± 0.697 ops/s
testParseLong thrpt 5 0.166 ± 0.021 ops/s
## Test load with 50% valid strings (50% strings contain non-digit symbols)
Benchmark Mode Cnt Score Error Units
testCharBetween thrpt 5 16.773 ± 0.401 ops/s
testCharAtIsDigit thrpt 5 8.917 ± 0.767 ops/s
testCharArrayIsDigit thrpt 5 6.553 ± 0.425 ops/s
testPattern thrpt 5 1.287 ± 0.057 ops/s
testIntStreamCodes thrpt 5 0.966 ± 0.051 ops/s
testParseLong thrpt 5 0.174 ± 0.013 ops/s
testParseInt thrpt 5 0.078 ± 0.001 ops/s
@State(Scope.Benchmark)
public class StringIsNumberBenchmark {
private static final long CYCLES = 1_000_000L;
private static final String[] STRINGS = {"12345678901","98765432177","58745896328","35741596328", "123456789a1", "1a345678901", "1234567890 "};
private static final Pattern PATTERN = Pattern.compile("\\d+");
@Benchmark
public void testPattern() {
for (int i = 0; i < CYCLES; i++) {
for (String s : STRINGS) {
boolean b = false;
b = PATTERN.matcher(s).matches();
}
}
}
@Benchmark
public void testParseLong() {
for (int i = 0; i < CYCLES; i++) {
for (String s : STRINGS) {
boolean b = false;
try {
Long.parseLong(s);
b = true;
} catch (NumberFormatException e) {
// no-op
}
}
}
}
@Benchmark
public void testCharArrayIsDigit() {
for (int i = 0; i < CYCLES; i++) {
for (String s : STRINGS) {
boolean b = false;
for (char c : s.toCharArray()) {
b = Character.isDigit(c);
if (!b) {
break;
}
}
}
}
}
@Benchmark
public void testCharAtIsDigit() {
for (int i = 0; i < CYCLES; i++) {
for (String s : STRINGS) {
boolean b = false;
for (int j = 0; j < s.length(); j++) {
b = Character.isDigit(s.charAt(j));
if (!b) {
break;
}
}
}
}
}
@Benchmark
public void testIntStreamCodes() {
for (int i = 0; i < CYCLES; i++) {
for (String s : STRINGS) {
boolean b = false;
b = s.chars().allMatch(c -> c > 47 && c < 58);
}
}
}
@Benchmark
public void testCharBetween() {
for (int i = 0; i < CYCLES; i++) {
for (String s : STRINGS) {
boolean b = false;
for (int j = 0; j < s.length(); j++) {
char charr = s.charAt(j);
b = '0' <= charr && charr <= '9';
if (!b) {
break;
}
}
}
}
}
}
charAt
instead of creating extra array and another using IntStream
of char codesUpvotes: 14
Reputation: 27862
Apache Commons Lang provides org.apache.commons.lang.StringUtils.isNumeric(CharSequence cs)
, which takes as an argument a String
and checks if it consists of purely numeric characters (including numbers from non-Latin scripts). That method returns false
if there are characters such as space, minus, plus, and decimal separators such as comma and dot.
Other methods of that class allow for further numeric checks.
Upvotes: 9
Reputation: 200
Character first_letter_or_number = query.charAt(0);
//------------------------------------------------------------------------------
if (Character.isDigit())
{
}
else if (Character.isLetter())
{
}
Upvotes: 1
Reputation: 746
You can also use NumberUtil.isCreatable(String str) from Apache Commons
Upvotes: 20
Reputation: 49
Below regexs can be used to check if a string has only number or not:
if (str.matches(".*[^0-9].*")) or if (str.matches(".*\\D.*"))
Both conditions above will return true
if String containts non-numbers. On false
, string has only numbers.
Upvotes: 4
Reputation: 37
import java.util.*;
class Class1 {
public static void main(String[] argh) {
boolean ans = CheckNumbers("123");
if (ans == true) {
System.out.println("String contains numbers only");
} else {
System.out.println("String contains other values as well");
}
}
public static boolean CheckNumbers(String input) {
for (int ctr = 0; ctr < input.length(); ctr++) {
if ("1234567890".contains(Character.valueOf(input.charAt(ctr)).toString())) {
continue;
} else {
return false;
}
}
return true;
}
}
Upvotes: 2
Reputation: 21616
This is how I would do it:
if(text.matches("^[0-9]*$") && text.length() > 2){
//...
}
The $
will avoid a partial match e.g; 1B
.
Upvotes: 22
Reputation: 48330
If you'll be processing the number as text, then change:
if (text.contains("[a-zA-Z]+") == false && text.length() > 2){
to:
if (text.matches("[0-9]+") && text.length() > 2) {
Instead of checking that the string doesn't contain alphabetic characters, check to be sure it contains only numerics.
If you actually want to use the numeric value, use Integer.parseInt()
or Double.parseDouble()
as others have explained below.
As a side note, it's generally considered bad practice to compare boolean values to true
or false
. Just use if (condition)
or if (!condition)
.
Upvotes: 434
Reputation: 128919
This code is already written. If you don't mind the (extremely) minor performance hit--which is probably no worse than doing a regex match--use Integer.parseInt() or Double.parseDouble(). That'll tell you right away if a String is only numbers (or is a number, as appropriate). If you need to handle longer strings of numbers, both BigInteger and BigDecimal sport constructors that accept Strings. Any of these will throw a NumberFormatException if you try to pass it a non-number (integral or decimal, based on the one you choose, of course). Alternately, depending on your requirements, just iterate the characters in the String and check Character.isDigit() and/or Character.isLetter().
Upvotes: 2
Reputation: 2561
There are lots of facilities to obtain numbers from String
s in Java (and vice versa). You may want to skip the regex part to spare yourself the complication of that.
For example, you could try and see what Double.parseDouble(String s)
returns for you. It should throw a NumberFormatException
if it does not find an appropriate value in the string. I would suggest this technique because you could actually make use of the value represented by the String
as a numeric type.
Upvotes: 2