Làm thế nào bạn sẽ kiểm tra nếu một Chuỗi là một số trước khi phân tích nó?
Integer.parseInt()
sẽ không phân tích được số điện thoại di động NumberFormatException
.
Làm thế nào bạn sẽ kiểm tra nếu một Chuỗi là một số trước khi phân tích nó?
Integer.parseInt()
sẽ không phân tích được số điện thoại di động NumberFormatException
.
Câu trả lời:
Với Apache Commons Lang 3.5 trở lên: NumberUtils.isCreatable
hoặc StringUtils.isNumeric
.
Với Apache Commons Lang 3.4 trở xuống: NumberUtils.isNumber
hoặc StringUtils.isNumeric
.
Bạn cũng có thể sử dụng StringUtils.isNumericSpace
trả về true
cho chuỗi trống và bỏ qua khoảng trắng bên trong chuỗi. Một cách khác là sử dụng NumberUtils.isParsable
về cơ bản kiểm tra số có thể phân tích cú pháp theo Java. (Các javadocs được liên kết chứa các ví dụ chi tiết cho từng phương thức.)
StringUtils.isNumeric()
có lẽ sẽ không thích hợp ở đây vì nó chỉ kiểm tra nếu chuỗi là một chuỗi các chữ số. Sẽ tốt cho hầu hết các số nguyên nhưng không phải như vậy đối với các số có số thập phân, dấu tách nhóm, v.v.
StringUtils
không hỗ trợ các dấu hiệu hàng đầu nhưng bạn nên kiểm tra NumberUtils.isCreatable
, nó hỗ trợ tiêu cực đúng cách.
Điều này thường được thực hiện với một hàm do người dùng định nghĩa đơn giản (nghĩa là hàm "isNumeric" của chính bạn).
Cái gì đó như:
public static boolean isNumeric(String str) {
try {
Double.parseDouble(str);
return true;
} catch(NumberFormatException e){
return false;
}
}
Tuy nhiên, nếu bạn gọi hàm này rất nhiều và bạn hy vọng nhiều kiểm tra không thành công do không phải là số thì hiệu suất của cơ chế này sẽ không tốt, vì bạn dựa vào ngoại lệ bị ném cho mỗi thất bại, đó là một hoạt động khá tốn kém.
Một cách tiếp cận khác có thể là sử dụng biểu thức chính quy để kiểm tra tính hợp lệ của một số:
public static boolean isNumeric(String str) {
return str.matches("-?\\d+(\\.\\d+)?"); //match a number with optional '-' and decimal.
}
Tuy nhiên, hãy cẩn thận với cơ chế RegEx ở trên, vì nó sẽ thất bại nếu bạn sử dụng các chữ số không phải là tiếng Ả Rập (tức là các chữ số khác từ 0 đến 9). Điều này là do phần "\ d" của RegEx sẽ chỉ khớp với [0-9] và thực tế không phải là nhận thức về số lượng quốc tế. (Cảm ơn OregonGhost đã chỉ ra điều này!)
Hoặc thậm chí một cách khác là sử dụng đối tượng java.text.NumberFormat tích hợp sẵn của Java để xem nếu sau khi phân tích chuỗi, vị trí của trình phân tích cú pháp nằm ở cuối chuỗi. Nếu có, chúng ta có thể giả sử toàn bộ chuỗi là số:
public static boolean isNumeric(String str) {
NumberFormat formatter = NumberFormat.getInstance();
ParsePosition pos = new ParsePosition(0);
formatter.parse(str, pos);
return str.length() == pos.getIndex();
}
.
trong biểu thức chính quy của bạn sẽ khớp với bất kỳ ký tự nào, không chỉ ký tự phân tách thập phân.
Nếu bạn đang dùng Android, thì bạn nên sử dụng:
android.text.TextUtils.isDigitsOnly(CharSequence str)
tài liệu có thể được tìm thấy ở đây
giữ cho nó đơn giản . hầu hết mọi người đều có thể "lập trình lại" (điều tương tự).
.
,-
Các biểu thức lambda 8.
String someString = "123123";
boolean isNumeric = someString.chars().allMatch( Character::isDigit );
Như @CraigTP đã đề cập trong câu trả lời xuất sắc của anh ấy, tôi cũng có những lo ngại về hiệu suất tương tự khi sử dụng Ngoại lệ để kiểm tra xem chuỗi có phải là số hay không. Vì vậy, tôi kết thúc việc tách chuỗi và sử dụng java.lang.Character.isDigit()
.
public static boolean isNumeric(String str)
{
for (char c : str.toCharArray())
{
if (!Character.isDigit(c)) return false;
}
return true;
}
Theo Javadoc , Character.isDigit(char)
sẽ nhận dạng chính xác các chữ số không phải là tiếng Latinh. Hiệu suất khôn ngoan, tôi nghĩ rằng một số so sánh N đơn giản trong đó N là số lượng ký tự trong chuỗi sẽ hiệu quả hơn về mặt tính toán so với thực hiện so khớp regex.
CẬP NHẬT: Như được chỉ ra bởi Jean-François Corbett trong bình luận, đoạn mã trên sẽ chỉ xác nhận các số nguyên dương, bao gồm phần lớn trường hợp sử dụng của tôi. Dưới đây là mã được cập nhật xác nhận chính xác các số thập phân theo ngôn ngữ mặc định được sử dụng trong hệ thống của bạn, với giả định rằng dấu tách thập phân chỉ xảy ra một lần trong chuỗi.
public static boolean isStringNumeric( String str )
{
DecimalFormatSymbols currentLocaleSymbols = DecimalFormatSymbols.getInstance();
char localeMinusSign = currentLocaleSymbols.getMinusSign();
if ( !Character.isDigit( str.charAt( 0 ) ) && str.charAt( 0 ) != localeMinusSign ) return false;
boolean isDecimalSeparatorFound = false;
char localeDecimalSeparator = currentLocaleSymbols.getDecimalSeparator();
for ( char c : str.substring( 1 ).toCharArray() )
{
if ( !Character.isDigit( c ) )
{
if ( c == localeDecimalSeparator && !isDecimalSeparatorFound )
{
isDecimalSeparatorFound = true;
continue;
}
return false;
}
}
return true;
}
toCharArray()
sẽ tạo một bản sao của mảng trong đối tượng String vì String là bất biến. Có lẽ nhanh hơn để sử dụng charAt(int index)
phương thức trên đối tượng String trực tiếp.
StringIndexOutOfBoundsException
khi vượt qua một chuỗi có độ dài 0. Có thể được sửa bằngif(str.length() == 0) return false;
Thư viện Guava của Google cung cấp một phương pháp trợ giúp tốt để thực hiện việc này : Ints.tryParse
. Bạn sử dụng nó như thế Integer.parseInt
nhưng nó trả về null
thay vì ném Ngoại lệ nếu chuỗi không phân tích thành số nguyên hợp lệ. Lưu ý rằng nó trả về Integer, không phải int, vì vậy bạn phải chuyển đổi / autobox nó trở lại int.
Thí dụ:
String s1 = "22";
String s2 = "22.2";
Integer oInt1 = Ints.tryParse(s1);
Integer oInt2 = Ints.tryParse(s2);
int i1 = -1;
if (oInt1 != null) {
i1 = oInt1.intValue();
}
int i2 = -1;
if (oInt2 != null) {
i2 = oInt2.intValue();
}
System.out.println(i1); // prints 22
System.out.println(i2); // prints -1
Tuy nhiên, kể từ phiên bản hiện tại - Guava r11 - nó vẫn được đánh dấu @Beta.
Tôi đã không điểm chuẩn nó. Nhìn vào mã nguồn có một số chi phí từ rất nhiều kiểm tra sự tỉnh táo nhưng cuối cùng họ sử dụng Character.digit(string.charAt(idx))
, tương tự, nhưng hơi khác so với, câu trả lời từ @Ibrahim ở trên. Không có ngoại lệ xử lý chi phí dưới vỏ bọc trong việc thực hiện của họ.
Không sử dụng Ngoại lệ để xác thực giá trị của bạn. Sử dụng libil Util thay vì apache NumberUtils:
NumberUtils.isNumber(myStringValue);
Chỉnh sửa :
Xin lưu ý rằng, nếu chuỗi của bạn bắt đầu bằng 0, NumberUtils sẽ diễn giải giá trị của bạn dưới dạng thập lục phân.
NumberUtils.isNumber("07") //true
NumberUtils.isNumber("08") //false
Number.isNumber()
.
Number.isNumber()
đã có mặt từ phiên bản đầu tiên của câu trả lời, ngày 24 tháng 9 '12 lúc 17:01.
Tại sao mọi người đều thúc đẩy các giải pháp ngoại lệ / regex?
Mặc dù tôi có thể hiểu hầu hết mọi người đều ổn khi sử dụng thử / bắt, nhưng nếu bạn muốn làm điều đó thường xuyên ... nó có thể cực kỳ đánh thuế.
Những gì tôi đã làm ở đây là lấy regex, các phương thức parseNumber () và phương thức tìm kiếm mảng để xem cái nào hiệu quả nhất. Lần này, tôi chỉ nhìn vào số nguyên.
public static boolean isNumericRegex(String str) {
if (str == null)
return false;
return str.matches("-?\\d+");
}
public static boolean isNumericArray(String str) {
if (str == null)
return false;
char[] data = str.toCharArray();
if (data.length <= 0)
return false;
int index = 0;
if (data[0] == '-' && data.length > 1)
index = 1;
for (; index < data.length; index++) {
if (data[index] < '0' || data[index] > '9') // Character.isDigit() can go here too.
return false;
}
return true;
}
public static boolean isNumericException(String str) {
if (str == null)
return false;
try {
/* int i = */ Integer.parseInt(str);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
Kết quả về tốc độ tôi nhận được là:
Done with: for (int i = 0; i < 10000000; i++)...
With only valid numbers ("59815833" and "-59815833"):
Array numeric took 395.808192 ms [39.5808192 ns each]
Regex took 2609.262595 ms [260.9262595 ns each]
Exception numeric took 428.050207 ms [42.8050207 ns each]
// Negative sign
Array numeric took 355.788273 ms [35.5788273 ns each]
Regex took 2746.278466 ms [274.6278466 ns each]
Exception numeric took 518.989902 ms [51.8989902 ns each]
// Single value ("1")
Array numeric took 317.861267 ms [31.7861267 ns each]
Regex took 2505.313201 ms [250.5313201 ns each]
Exception numeric took 239.956955 ms [23.9956955 ns each]
// With Character.isDigit()
Array numeric took 400.734616 ms [40.0734616 ns each]
Regex took 2663.052417 ms [266.3052417 ns each]
Exception numeric took 401.235906 ms [40.1235906 ns each]
With invalid characters ("5981a5833" and "a"):
Array numeric took 343.205793 ms [34.3205793 ns each]
Regex took 2608.739933 ms [260.8739933 ns each]
Exception numeric took 7317.201775 ms [731.7201775 ns each]
// With a single character ("a")
Array numeric took 291.695519 ms [29.1695519 ns each]
Regex took 2287.25378 ms [228.725378 ns each]
Exception numeric took 7095.969481 ms [709.5969481 ns each]
With null:
Array numeric took 214.663834 ms [21.4663834 ns each]
Regex took 201.395992 ms [20.1395992 ns each]
Exception numeric took 233.049327 ms [23.3049327 ns each]
Exception numeric took 6603.669427 ms [660.3669427 ns each] if there is no if/null check
Tuyên bố miễn trừ trách nhiệm: Tôi không khẳng định các phương pháp này được tối ưu hóa 100%, chúng chỉ để trình diễn dữ liệu
Các ngoại lệ giành được khi và chỉ khi số đó có 4 ký tự trở xuống và mỗi chuỗi luôn là một số ... trong trường hợp nào, tại sao thậm chí có một kiểm tra?
Nói tóm lại, sẽ vô cùng đau đớn nếu bạn thường xuyên gặp phải những con số không hợp lệ với lần thử / bắt, điều này có ý nghĩa. Một quy tắc quan trọng tôi luôn tuân theo là KHÔNG BAO GIỜ sử dụng thử / bắt cho luồng chương trình . Đây là một ví dụ tại sao.
Thật thú vị, đơn giản nếu char <0 || > 9 cực kỳ đơn giản để viết, dễ nhớ (và nên hoạt động với nhiều ngôn ngữ) và chiến thắng hầu hết các kịch bản thử nghiệm.
Nhược điểm duy nhất là tôi đoán Integer.parseInt () có thể xử lý các số không phải ASCII, trong khi phương thức tìm kiếm mảng thì không.
Đối với những người thắc mắc tại sao tôi nói thật dễ nhớ mảng ký tự một, nếu bạn biết không có dấu hiệu tiêu cực, bạn có thể dễ dàng thoát khỏi thứ gì đó cô đọng như thế này:
public static boolean isNumericArray(String str) {
if (str == null)
return false;
for (char c : str.toCharArray())
if (c < '0' || c > '9')
return false;
return true;
Cuối cùng, như là một lưu ý cuối cùng, tôi tò mò về toán tử ám sát trong ví dụ được chấp nhận với tất cả các phiếu bầu. Thêm vào sự phân công của
double d = Double.parseDouble(...)
không chỉ vô dụng vì bạn thậm chí không sử dụng giá trị, mà còn lãng phí thời gian xử lý và tăng thời gian chạy thêm vài nano giây (dẫn đến tăng 100-200 ms trong các thử nghiệm). Tôi không thể hiểu tại sao mọi người sẽ làm điều đó vì nó thực sự là công việc làm thêm để giảm hiệu suất.
Bạn sẽ nghĩ rằng điều đó sẽ được tối ưu hóa ... mặc dù có lẽ tôi nên kiểm tra mã byte và xem trình biên dịch đang làm gì. Điều đó không giải thích được tại sao nó luôn xuất hiện dài hơn đối với tôi mặc dù nếu nó bằng cách nào đó được tối ưu hóa ... do đó tôi tự hỏi chuyện gì đang xảy ra. Như một lưu ý: Bằng cách dài hơn, tôi có nghĩa là chạy thử nghiệm cho 10000000 lần lặp và chạy chương trình đó nhiều lần (10 lần +) luôn cho thấy nó chậm hơn.
EDIT: Đã cập nhật một bài kiểm tra cho Character.isDigit ()
public static boolean isNumeric(String str)
{
return str.matches("-?\\d+(.\\d+)?");
}
Biểu thức chính quy của CraigTP (hiển thị ở trên) tạo ra một số dương tính giả. Ví dụ: "23y4" sẽ được tính là một số vì '.' phù hợp với bất kỳ ký tự không phải là dấu thập phân.
Ngoài ra, nó sẽ từ chối bất kỳ số nào có dấu '+' hàng đầu
Một giải pháp thay thế để tránh hai vấn đề nhỏ này là
public static boolean isNumeric(String str)
{
return str.matches("[+-]?\\d*(\\.\\d+)?");
}
true
cho một cộng "+"
hoặc trừ "-"
và false
cho"0."
matches("-?\\d+([.]\\d+)?")
Chúng ta có thể thử thay thế tất cả các số từ chuỗi đã cho bằng ("") tức là khoảng trống và nếu sau đó độ dài của chuỗi bằng 0 thì chúng ta có thể nói rằng chuỗi đã cho chỉ chứa các số. [Nếu bạn thấy câu trả lời này hữu ích thì vui lòng xem xét bỏ phiếu] Ví dụ:
boolean isNumber(String str){
if(str.length() == 0)
return false; //To check if string is empty
if(str.charAt(0) == '-')
str = str.replaceFirst("-","");// for handling -ve numbers
System.out.println(str);
str = str.replaceFirst("\\.",""); //to check if it contains more than one decimal points
if(str.length() == 0)
return false; // to check if it is empty string after removing -ve sign and decimal point
System.out.println(str);
return str.replaceAll("[0-9]","").length() == 0;
}
""
một số nhưng "3.14"
và "-1"
không?
Bạn có thể sử dụng NumberFormat#parse
:
try
{
NumberFormat.getInstance().parse(value);
}
catch(ParseException e)
{
// Not a number.
}
value
.
Nếu bạn sử dụng java để phát triển ứng dụng Android, bạn có thể sử dụng chức năng TextUtils.isDigitsOnly .
Đây là câu trả lời của tôi cho vấn đề.
Một phương thức bắt tất cả tiện lợi mà bạn có thể sử dụng để phân tích bất kỳ Chuỗi nào với bất kỳ loại trình phân tích cú pháp nào : isParsable(Object parser, String str)
. Trình phân tích cú pháp có thể là một Class
hoặc một object
. Điều này cũng sẽ cho phép bạn sử dụng các trình phân tích cú pháp tùy chỉnh mà bạn đã viết và sẽ hoạt động cho mọi tình huống, ví dụ:
isParsable(Integer.class, "11");
isParsable(Double.class, "11.11");
Object dateFormater = new java.text.SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");
isParsable(dateFormater, "2001.07.04 AD at 12:08:56 PDT");
Đây là mã của tôi hoàn thành với các mô tả phương pháp.
import java.lang.reflect.*;
/**
* METHOD: isParsable<p><p>
*
* This method will look through the methods of the specified <code>from</code> parameter
* looking for a public method name starting with "parse" which has only one String
* parameter.<p>
*
* The <code>parser</code> parameter can be a class or an instantiated object, eg:
* <code>Integer.class</code> or <code>new Integer(1)</code>. If you use a
* <code>Class</code> type then only static methods are considered.<p>
*
* When looping through potential methods, it first looks at the <code>Class</code> associated
* with the <code>parser</code> parameter, then looks through the methods of the parent's class
* followed by subsequent ancestors, using the first method that matches the criteria specified
* above.<p>
*
* This method will hide any normal parse exceptions, but throws any exceptions due to
* programmatic errors, eg: NullPointerExceptions, etc. If you specify a <code>parser</code>
* parameter which has no matching parse methods, a NoSuchMethodException will be thrown
* embedded within a RuntimeException.<p><p>
*
* Example:<br>
* <code>isParsable(Boolean.class, "true");<br>
* isParsable(Integer.class, "11");<br>
* isParsable(Double.class, "11.11");<br>
* Object dateFormater = new java.text.SimpleDateFormat("yyyy.MM.dd G 'at' HH:mm:ss z");<br>
* isParsable(dateFormater, "2001.07.04 AD at 12:08:56 PDT");<br></code>
* <p>
*
* @param parser The Class type or instantiated Object to find a parse method in.
* @param str The String you want to parse
*
* @return true if a parse method was found and completed without exception
* @throws java.lang.NoSuchMethodException If no such method is accessible
*/
public static boolean isParsable(Object parser, String str) {
Class theClass = (parser instanceof Class? (Class)parser: parser.getClass());
boolean staticOnly = (parser == theClass), foundAtLeastOne = false;
Method[] methods = theClass.getMethods();
// Loop over methods
for (int index = 0; index < methods.length; index++) {
Method method = methods[index];
// If method starts with parse, is public and has one String parameter.
// If the parser parameter was a Class, then also ensure the method is static.
if(method.getName().startsWith("parse") &&
(!staticOnly || Modifier.isStatic(method.getModifiers())) &&
Modifier.isPublic(method.getModifiers()) &&
method.getGenericParameterTypes().length == 1 &&
method.getGenericParameterTypes()[0] == String.class)
{
try {
foundAtLeastOne = true;
method.invoke(parser, str);
return true; // Successfully parsed without exception
} catch (Exception exception) {
// If invoke problem, try a different method
/*if(!(exception instanceof IllegalArgumentException) &&
!(exception instanceof IllegalAccessException) &&
!(exception instanceof InvocationTargetException))
continue; // Look for other parse methods*/
// Parse method refuses to parse, look for another different method
continue; // Look for other parse methods
}
}
}
// No more accessible parse method could be found.
if(foundAtLeastOne) return false;
else throw new RuntimeException(new NoSuchMethodException());
}
/**
* METHOD: willParse<p><p>
*
* A convienence method which calls the isParseable method, but does not throw any exceptions
* which could be thrown through programatic errors.<p>
*
* Use of {@link #isParseable(Object, String) isParseable} is recommended for use so programatic
* errors can be caught in development, unless the value of the <code>parser</code> parameter is
* unpredictable, or normal programtic exceptions should be ignored.<p>
*
* See {@link #isParseable(Object, String) isParseable} for full description of method
* usability.<p>
*
* @param parser The Class type or instantiated Object to find a parse method in.
* @param str The String you want to parse
*
* @return true if a parse method was found and completed without exception
* @see #isParseable(Object, String) for full description of method usability
*/
public static boolean willParse(Object parser, String str) {
try {
return isParsable(parser, str);
} catch(Throwable exception) {
return false;
}
}
Để chỉ khớp với mười số nguyên cơ bản, chỉ chứa các chữ số ASCII, hãy sử dụng:
public static boolean isNumeric(String maybeNumeric) {
return maybeNumeric != null && maybeNumeric.matches("[0-9]+");
}
Một cách tiếp cận thực hiện tốt tránh bắt thử và xử lý số âm và ký hiệu khoa học.
Pattern PATTERN = Pattern.compile( "^(-?0|-?[1-9]\\d*)(\\.\\d+)?(E\\d+)?$" );
public static boolean isNumeric( String value )
{
return value != null && PATTERN.matcher( value ).matches();
}
Đây là lớp của tôi để kiểm tra nếu một chuỗi là số. Nó cũng sửa các chuỗi số:
Bạn đi đây ...
public class NumUtils {
/**
* Transforms a string to an integer. If no numerical chars returns a String "0".
*
* @param str
* @return retStr
*/
static String makeToInteger(String str) {
String s = str;
double d;
d = Double.parseDouble(makeToDouble(s));
int i = (int) (d + 0.5D);
String retStr = String.valueOf(i);
System.out.printf(retStr + " ");
return retStr;
}
/**
* Transforms a string to an double. If no numerical chars returns a String "0".
*
* @param str
* @return retStr
*/
static String makeToDouble(String str) {
Boolean dotWasFound = false;
String orgStr = str;
String retStr;
int firstDotPos = 0;
Boolean negative = false;
//check if str is null
if(str.length()==0){
str="0";
}
//check if first sign is "-"
if (str.charAt(0) == '-') {
negative = true;
}
//check if str containg any number or else set the string to '0'
if (!str.matches(".*\\d+.*")) {
str = "0";
}
//Replace ',' with '.' (for some european users who use the ',' as decimal separator)
str = str.replaceAll(",", ".");
str = str.replaceAll("[^\\d.]", "");
//Removes the any second dots
for (int i_char = 0; i_char < str.length(); i_char++) {
if (str.charAt(i_char) == '.') {
dotWasFound = true;
firstDotPos = i_char;
break;
}
}
if (dotWasFound) {
String befDot = str.substring(0, firstDotPos + 1);
String aftDot = str.substring(firstDotPos + 1, str.length());
aftDot = aftDot.replaceAll("\\.", "");
str = befDot + aftDot;
}
//Removes zeros from the begining
double uglyMethod = Double.parseDouble(str);
str = String.valueOf(uglyMethod);
//Removes the .0
str = str.replaceAll("([0-9])\\.0+([^0-9]|$)", "$1$2");
retStr = str;
if (negative) {
retStr = "-"+retStr;
}
return retStr;
}
static boolean isNumeric(String str) {
try {
double d = Double.parseDouble(str);
} catch (NumberFormatException nfe) {
return false;
}
return true;
}
}
Kết hợp Regex
Dưới đây là một ví dụ khác được nâng cấp regex "CraigTP" phù hợp với nhiều xác nhận hơn.
public static boolean isNumeric(String str)
{
return str.matches("^(?:(?:\\-{1})?\\d+(?:\\.{1}\\d+)?)$");
}
Kiểm tra Regex
1 -- **VALID**
1. -- INVALID
1.. -- INVALID
1.1 -- **VALID**
1.1.1 -- INVALID
-1 -- **VALID**
--1 -- INVALID
-1. -- INVALID
-1.1 -- **VALID**
-1.1.1 -- INVALID
Các ngoại lệ đắt tiền, nhưng trong trường hợp này, RegEx mất nhiều thời gian hơn. Mã dưới đây cho thấy một thử nghiệm đơn giản của hai chức năng - một sử dụng ngoại lệ và một sử dụng regex. Trên máy của tôi, phiên bản RegEx chậm hơn 10 lần so với ngoại lệ.
import java.util.Date;
public class IsNumeric {
public static boolean isNumericOne(String s) {
return s.matches("-?\\d+(\\.\\d+)?"); //match a number with optional '-' and decimal.
}
public static boolean isNumericTwo(String s) {
try {
Double.parseDouble(s);
return true;
} catch (Exception e) {
return false;
}
}
public static void main(String [] args) {
String test = "12345.F";
long before = new Date().getTime();
for(int x=0;x<1000000;++x) {
//isNumericTwo(test);
isNumericOne(test);
}
long after = new Date().getTime();
System.out.println(after-before);
}
}
// vui lòng kiểm tra mã bên dưới
public static boolean isDigitsOnly(CharSequence str) {
final int len = str.length();
for (int i = 0; i < len; i++) {
if (!Character.isDigit(str.charAt(i))) {
return false;
}
}
return true;
}
// only int
public static boolean isNumber(int num)
{
return (num >= 48 && c <= 57); // 0 - 9
}
// is type of number including . - e E
public static boolean isNumber(String s)
{
boolean isNumber = true;
for(int i = 0; i < s.length() && isNumber; i++)
{
char c = s.charAt(i);
isNumber = isNumber & (
(c >= '0' && c <= '9') || (c == '.') || (c == 'e') || (c == 'E') || (c == '')
);
}
return isInteger;
}
// is type of number
public static boolean isInteger(String s)
{
boolean isInteger = true;
for(int i = 0; i < s.length() && isInteger; i++)
{
char c = s.charAt(i);
isInteger = isInteger & ((c >= '0' && c <= '9'));
}
return isInteger;
}
public static boolean isNumeric(String s)
{
try
{
Double.parseDouble(s);
return true;
}
catch (Exception e)
{
return false;
}
}
Đây là một ví dụ đơn giản cho kiểm tra này:
public static boolean isNumericString(String input) {
boolean result = false;
if(input != null && input.length() > 0) {
char[] charArray = input.toCharArray();
for(char c : charArray) {
if(c >= '0' && c <= '9') {
// it is a digit
result = true;
} else {
result = false;
break;
}
}
}
return result;
}
Bạn có thể sử dụng đối tượng java.util.Scanner.
public static boolean isNumeric(String inputData) {
Scanner sc = new Scanner(inputData);
return sc.hasNextInt();
}
Tôi đã sửa đổi giải pháp của CraigTP để chấp nhận ký hiệu khoa học và cả dấu chấm và dấu phẩy dưới dạng dấu tách thập phân
^-?\d+([,\.]\d+)?([eE]-?\d+)?$
thí dụ
var re = new RegExp("^-?\d+([,\.]\d+)?([eE]-?\d+)?$");
re.test("-6546"); // true
re.test("-6546355e-4456"); // true
re.test("-6546.355e-4456"); // true, though debatable
re.test("-6546.35.5e-4456"); // false
re.test("-6546.35.5e-4456.6"); // false
Đó là lý do tại sao tôi thích cách tiếp cận Thử * trong .NET. Ngoài phương thức Parse truyền thống giống như phương thức Java, bạn cũng có một phương thức TryPude. Tôi không giỏi về cú pháp Java (ngoài tham số?), Vì vậy vui lòng coi sau đây là một loại mã giả. Nó sẽ làm cho khái niệm rõ ràng mặc dù.
boolean parseInteger(String s, out int number)
{
try {
number = Integer.parseInt(myString);
return true;
} catch(NumberFormatException e) {
return false;
}
}
Sử dụng:
int num;
if (parseInteger("23", out num)) {
// Do something with num.
}
Phân tích cú pháp (nghĩa là với Integer#parseInt
) và chỉ cần bắt ngoại lệ. =)
Để làm rõ: Hàm parseInt kiểm tra xem nó có thể phân tích số trong mọi trường hợp (rõ ràng) không và nếu bạn muốn phân tích cú pháp bằng mọi cách, bạn sẽ không thực hiện bất kỳ hiệu suất nào bằng cách thực hiện phân tích cú pháp.
Nếu bạn không muốn phân tích nó (hoặc phân tích nó rất, rất hiếm khi), bạn có thể muốn làm điều đó khác đi tất nhiên.
Bạn có thể sử dụng NumberUtils.isCreatable () từ Apache Commons Lang .
Vì NumberUtils.isNumber sẽ không được chấp nhận trong 4.0, nên sử dụng NumberUtils.isCreatable () để thay thế.
Luồng Java 8, biểu thức lambda, giao diện chức năng
Tất cả các trường hợp được xử lý ( chuỗi null, chuỗi rỗng, v.v. )
String someString = null; // something="", something="123abc", something="123123"
boolean isNumeric = Stream.of(someString)
.filter(s -> s != null && !s.isEmpty())
.filter(Pattern.compile("\\D").asPredicate().negate())
.mapToLong(Long::valueOf)
.boxed()
.findAny()
.isPresent();
Tôi đã minh họa một số điều kiện để kiểm tra số và số thập phân mà không sử dụng bất kỳ API nào,
Kiểm tra độ dài số 1 chữ số
Character.isDigit(char)
Kiểm tra số Chiều dài sửa chữa (Giả sử chiều dài là 6)
String number = "132452";
if(number.matches("([0-9]{6})"))
System.out.println("6 digits number identified");
Kiểm tra số Độ dài thay đổi giữa (Giả sử 4 đến 6 chiều dài)
// {n,m} n <= length <= m
String number = "132452";
if(number.matches("([0-9]{4,6})"))
System.out.println("Number Identified between 4 to 6 length");
String number = "132";
if(!number.matches("([0-9]{4,6})"))
System.out.println("Number not in length range or different format");
Kiểm tra số thập phân Độ dài thay đổi giữa (Giả sử 4 đến 7 chiều dài)
// It will not count the '.' (Period) in length
String decimal = "132.45";
if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Numbers Identified between 4 to 7");
String decimal = "1.12";
if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Numbers Identified between 4 to 7");
String decimal = "1234";
if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Numbers Identified between 4 to 7");
String decimal = "-10.123";
if(decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Numbers Identified between 4 to 7");
String decimal = "123..4";
if(!decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Decimal not in range or different format");
String decimal = "132";
if(!decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Decimal not in range or different format");
String decimal = "1.1";
if(!decimal.matches("(-?[0-9]+(\.)?[0-9]*){4,6}"))
System.out.println("Decimal not in range or different format");
Hy vọng nó sẽ giúp được nhiều người.
Dựa trên các câu trả lời khác, tôi đã tự viết và nó không sử dụng các mẫu hoặc phân tích cú pháp với kiểm tra ngoại lệ.
Nó kiểm tra tối đa một dấu trừ và kiểm tra tối đa một dấu thập phân.
Dưới đây là một số ví dụ và kết quả của họ:
"1", "-1", "-1.5" và "-1.556" trả về đúng
"1..5", "1A.5", "1.5D", "-" và "--1" trả về sai
Lưu ý: Nếu cần, bạn có thể sửa đổi điều này để chấp nhận tham số Địa điểm và chuyển thông số đó vào các lệnh gọi DecimalFormatSymbols.getInstance () để sử dụng một Địa điểm cụ thể thay vì tham số hiện tại.
public static boolean isNumeric(final String input) {
//Check for null or blank string
if(input == null || input.isBlank()) return false;
//Retrieve the minus sign and decimal separator characters from the current Locale
final var localeMinusSign = DecimalFormatSymbols.getInstance().getMinusSign();
final var localeDecimalSeparator = DecimalFormatSymbols.getInstance().getDecimalSeparator();
//Check if first character is a minus sign
final var isNegative = input.charAt(0) == localeMinusSign;
//Check if string is not just a minus sign
if (isNegative && input.length() == 1) return false;
var isDecimalSeparatorFound = false;
//If the string has a minus sign ignore the first character
final var startCharIndex = isNegative ? 1 : 0;
//Check if each character is a number or a decimal separator
//and make sure string only has a maximum of one decimal separator
for (var i = startCharIndex; i < input.length(); i++) {
if(!Character.isDigit(input.charAt(i))) {
if(input.charAt(i) == localeDecimalSeparator && !isDecimalSeparatorFound) {
isDecimalSeparatorFound = true;
} else return false;
}
}
return true;
}
Đây là hai phương pháp có thể hoạt động. (Không sử dụng Ngoại lệ). Lưu ý: Java là một giá trị truyền theo mặc định và giá trị của Chuỗi là địa chỉ của dữ liệu đối tượng của Chuỗi. Vì vậy, khi bạn đang làm
stringNumber = stringNumber.replaceAll(" ", "");
Bạn đã thay đổi giá trị đầu vào để không có khoảng trắng. Bạn có thể loại bỏ dòng đó nếu bạn muốn.
private boolean isValidStringNumber(String stringNumber)
{
if(stringNumber.isEmpty())
{
return false;
}
stringNumber = stringNumber.replaceAll(" ", "");
char [] charNumber = stringNumber.toCharArray();
for(int i =0 ; i<charNumber.length ;i++)
{
if(!Character.isDigit(charNumber[i]))
{
return false;
}
}
return true;
}
Đây là một phương pháp khác trong trường hợp bạn muốn cho phép thả nổi Phương pháp này được cho là cho phép các số trong biểu mẫu vượt qua 1.123,123,123,123,123.123 tôi vừa thực hiện và tôi nghĩ rằng nó cần thử nghiệm thêm để đảm bảo nó hoạt động.
private boolean isValidStringTrueNumber(String stringNumber)
{
if(stringNumber.isEmpty())
{
return false;
}
stringNumber = stringNumber.replaceAll(" ", "");
int countOfDecimalPoint = 0;
boolean decimalPointPassed = false;
boolean commaFound = false;
int countOfDigitsBeforeDecimalPoint = 0;
int countOfDigitsAfterDecimalPoint =0 ;
int commaCounter=0;
int countOfDigitsBeforeFirstComma = 0;
char [] charNumber = stringNumber.toCharArray();
for(int i =0 ; i<charNumber.length ;i++)
{
if((commaCounter>3)||(commaCounter<0))
{
return false;
}
if(!Character.isDigit(charNumber[i]))//Char is not a digit.
{
if(charNumber[i]==',')
{
if(decimalPointPassed)
{
return false;
}
commaFound = true;
//check that next three chars are only digits.
commaCounter +=3;
}
else if(charNumber[i]=='.')
{
decimalPointPassed = true;
countOfDecimalPoint++;
}
else
{
return false;
}
}
else //Char is a digit.
{
if ((commaCounter>=0)&&(commaFound))
{
if(!decimalPointPassed)
{
commaCounter--;
}
}
if(!commaFound)
{
countOfDigitsBeforeFirstComma++;
}
if(!decimalPointPassed)
{
countOfDigitsBeforeDecimalPoint++;
}
else
{
countOfDigitsAfterDecimalPoint++;
}
}
}
if((commaFound)&&(countOfDigitsBeforeFirstComma>3))
{
return false;
}
if(countOfDecimalPoint>1)
{
return false;
}
if((decimalPointPassed)&&((countOfDigitsBeforeDecimalPoint==0)||(countOfDigitsAfterDecimalPoint==0)))
{
return false;
}
return true;
}