Bir Dizenin ayrıştırılmadan önce bir sayı olup olmadığını nasıl kontrol edersiniz?
Integer.parseInt()
cep telefonu numaraları ile ayrıştırılamaz NumberFormatException
.
Bir Dizenin ayrıştırılmadan önce bir sayı olup olmadığını nasıl kontrol edersiniz?
Integer.parseInt()
cep telefonu numaraları ile ayrıştırılamaz NumberFormatException
.
Yanıtlar:
İle Apache Commons Lang 3.5 ve üzeri: NumberUtils.isCreatable
ya StringUtils.isNumeric
.
İle Apache Commons Lang 3.4 ve önceki sürümleri: NumberUtils.isNumber
ya StringUtils.isNumeric
.
Boş dizeler için StringUtils.isNumericSpace
döndüren true
ve dizedeki iç boşlukları yoksayanları da kullanabilirsiniz . Bir başka yol da, NumberUtils.isParsable
Java'ya göre sayının temelde ayrıştırılabileceğini kontrol etmektir. (Bağlantılı javadoclar her yöntem için ayrıntılı örnekler içerir.)
StringUtils.isNumeric()
muhtemelen dizenin bir basamak dizisi olup olmadığını kontrol ettiğinden burada uygun olmaz. Çoğu ints için iyi olurdu, ancak ondalıklı sayılar, grup ayırıcılar, vb. İçin değil
StringUtils
önde gelen işaretleri NumberUtils.isCreatable
desteklemiyor, ancak kontrol etmelisin , negatifleri düzgün bir şekilde destekliyor.
Bu genellikle kullanıcı tarafından tanımlanmış basit bir işlevle yapılır (yani, kendi rollerinizin "isNumeric" işlevi).
Gibi bir şey:
public static boolean isNumeric(String str) {
try {
Double.parseDouble(str);
return true;
} catch(NumberFormatException e){
return false;
}
}
Bununla birlikte, bu işlevi çok fazla çağırıyorsanız ve bir sayı olmaması nedeniyle kontrollerin çoğunun başarısız olmasını bekliyorsanız, bu mekanizmanın performansı büyük olmayacaktır, çünkü her hata için atılan istisnalara güveniyorsunuz, ki bu oldukça pahalı bir işlemdir.
Alternatif bir yaklaşım, bir sayı olmanın geçerliliğini kontrol etmek için düzenli bir ifade kullanmak olabilir:
public static boolean isNumeric(String str) {
return str.matches("-?\\d+(\\.\\d+)?"); //match a number with optional '-' and decimal.
}
Bununla birlikte, yukarıdaki RegEx mekanizmasına dikkat edin, çünkü Arapça olmayan rakamlar (örn. 0 ila 9 dışındaki sayılar) başarısız olur. Bunun nedeni RegEx'in "\ d" kısmının yalnızca [0-9] ile eşleşmesi ve uluslararası olarak sayısal olarak farkında olmamasıdır. (Bunu işaret ettiği için OregonGhost'a teşekkürler!)
Ya da başka bir alternatif, dizeyi ayrıştırdıktan sonra ayrıştırıcı konumunun dizenin sonunda olup olmadığını görmek için Java'nın yerleşik java.text.NumberFormat nesnesini kullanmaktır. Öyleyse, dizenin tamamının sayısal olduğunu varsayabiliriz:
public static boolean isNumeric(String str) {
NumberFormat formatter = NumberFormat.getInstance();
ParsePosition pos = new ParsePosition(0);
formatter.parse(str, pos);
return str.length() == pos.getIndex();
}
.
senin regex herhangi bir karakter değil, sadece ondalık ayırıcı karakteri ile eşleşir.
android iseniz, o zaman kullanmalısınız:
android.text.TextUtils.isDigitsOnly(CharSequence str)
belgeleri burada bulabilirsiniz
basit olsun . çoğunlukla herkes "yeniden programlayabilir" (aynı şey).
.
,-
Java 8 lambda ifadeleri.
String someString = "123123";
boolean isNumeric = someString.chars().allMatch( Character::isDigit );
@CraigTP'nin mükemmel cevabında belirttiği gibi, dizenin sayısal olup olmadığını test etmek için İstisnalar kullanma konusunda da benzer performans endişelerim var. Böylece dize bölmek ve kullanmak sonunda java.lang.Character.isDigit()
.
public static boolean isNumeric(String str)
{
for (char c : str.toCharArray())
{
if (!Character.isDigit(c)) return false;
}
return true;
}
Javadoc'a göre , Character.isDigit(char)
Latin olmayan rakamları doğru bir şekilde tanıyacak. Performans açısından, ben n dizede karakter sayısı basit bir N sayısı karşılaştırma bir regex eşleştirme yapmak daha hesaplama açısından verimli olacağını düşünüyorum.
GÜNCELLEME: Yorumda Jean-François Corbett'in işaret ettiği gibi, yukarıdaki kod sadece benim kullanım durumumun çoğunu kapsayan pozitif tam sayıları doğrulayacaktır. Aşağıda, ondalık sayıları sisteminizde kullanılan varsayılan yerel ayara göre doğrulayan ve ondalık ayırıcının dizede yalnızca bir kez oluştuğu varsayılarak güncellenen kod bulunmaktadır.
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()
Karakter dizileri değişmez çünkü String nesnesinde dizinin bir kopyasını oluşturur. Muhtemelen charAt(int index)
doğrudan String nesnesindeki yöntemi kullanmak daha hızlıdır .
StringIndexOutOfBoundsException
Uzunluğu 0 olan bir dize geçtiğinde üretilecekif(str.length() == 0) return false;
Google'ın Guava kütüphanesi bunu yapmak için güzel bir yardımcı yöntem sağlar: Ints.tryParse
. Bunu gibi kullanırsınız, Integer.parseInt
ancak null
dize geçerli bir tamsayıya ayrıştırmazsa bir İstisna atmak yerine geri döner . İnt yerine Integer döndürdüğünü unutmayın, bu yüzden int'e dönüştürmek / otomatik kutuya dönüştürmek zorundasınız.
Misal:
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
Bununla birlikte, mevcut sürümden - Guava r11 - hala @Beta olarak işaretlenmiştir.
Ben kıyaslama yapmadım. Kaynak koduna baktığımızda, birçok akıl sağlığı kontrolünden bir miktar yük var, ancak sonunda Character.digit(string.charAt(idx))
yukarıdaki @Ibrahim'den gelen cevabı benzer, ama biraz farklı kullanıyorlar. Uygulamalarında örtülerin altında bir istisna işleme yükü yoktur.
Değerlerinizi doğrulamak için İstisnalar kullanmayın. Apache NumberUtils gibi Util kütüphanelerini kullanın:
NumberUtils.isNumber(myStringValue);
Düzenle :
Dizeniz 0 ile başlıyorsa, NumberUtils'in değerinizi onaltılık olarak yorumlayacağını lütfen unutmayın.
NumberUtils.isNumber("07") //true
NumberUtils.isNumber("08") //false
Number.isNumber()
.
Number.isNumber()
ilk sürümünde, 24 Eylül 'de 17: 01'de mevcut olduğunu gösterir .
Neden herkes istisna / normal ifade çözümleri için baskı yapıyor?
Çoğu insanın dene / yakala ile iyi olduğunu anlayabiliyorum, ancak sık sık yapmak istiyorsanız ... son derece vergilendirici olabilir.
Burada ne yaptı regex, parseNumber () yöntemleri ve en verimli olduğunu görmek için dizi arama yöntemi almak oldu. Bu sefer sadece tam sayılara baktım.
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;
}
Aldığım hızdaki sonuçlar:
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
Feragatname: Bu yöntemlerin% 100 optimize edildiğini iddia etmiyorum, sadece verilerin gösterilmesi içindir
İstisnalar yalnızca sayı 4 karakter veya daha azsa ve her karakter dizisi her zaman bir sayı ise kazanılır ... bu durumda neden bir çekiniz olur?
Kısacası, try / catch ile geçersiz sayılara sık sık girmeniz son derece acı vericidir, bu da mantıklıdır. Her zaman takip ettiğim önemli bir kural ASLA program akışı için try / catch kullanmayın . Bunun bir örneği.
İlginçtir, eğer char <0 || > 9 yazmak son derece basitti, hatırlaması kolay (ve birden çok dilde çalışması gerekiyor) ve neredeyse tüm test senaryolarını kazanıyor.
Tek dezavantajı dizi arama yöntemi değil iken Integer.parseInt () olmayan ASCII sayıları işleyebilir tahmin olduğunu.
Neden bir karakter dizisini hatırlamak kolay dediğimi merak edenler için, olumsuz işaret olmadığını biliyorsanız, bu şekilde yoğunlaştırılmış bir şeyle kolayca kurtulabilirsiniz:
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;
Son olarak, kabul edilen örnekte görevlendirme operatörünü tüm oylarla merak ettim. Ekleme
double d = Double.parseDouble(...)
sadece değeri kullanmazsınız, çünkü işlem süresini harcar ve çalışma süresini birkaç nanosaniye arttırır (bu da testlerde 100-200 ms'lik bir artışa neden olur). Performansı azaltmak için fazladan bir çalışma olduğu için neden bunu herkesin yapacağını anlayamıyorum.
Bunun optimize edileceğini düşünürdünüz ... yine de bayt kodunu kontrol etmeli ve derleyicinin ne yaptığını görmeliyim. Bu neden benim için her zaman daha uzun ortaya çıktığını açıklamıyor olsa da, bir şekilde optimize edilirse ... Bu yüzden neler olduğunu merak ediyorum. Not: Daha uzun olarak, testi 10000000 yineleme için çalıştırmak ve o programı birden çok kez (10x +) çalıştırmak her zaman daha yavaş olduğunu gösterdi.
EDIT: Character.isDigit () için bir test güncellendi
public static boolean isNumeric(String str)
{
return str.matches("-?\\d+(.\\d+)?");
}
CraigTP'nin düzenli ifadesi (yukarıda gösterilmiştir) bazı yanlış pozitifler üretir. Örneğin, "23y4" sayı olarak sayılacaktır çünkü '.' ondalık işareti olmayan herhangi bir karakterle eşleşir.
Ayrıca önde gelen '+' ile herhangi bir sayıyı reddeder
Bu iki küçük problemden kaçınan bir alternatif
public static boolean isNumeric(String str)
{
return str.matches("[+-]?\\d*(\\.\\d+)?");
}
true
tek artı için "+"
veya eksi "-"
ve false
için"0."
matches("-?\\d+([.]\\d+)?")
Verilen dizeden gelen tüm sayıları ("") yani boşluk ile değiştirmeyi deneyebiliriz ve bundan sonra dizenin uzunluğu sıfırsa, verilen dizenin yalnızca sayılar içerdiğini söyleyebiliriz. [Bu yanıtı yararlı bulduysanız, lütfen oylamayı düşünün] Örnek:
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;
}
""
bir sayı ama "3.14"
ve "-1"
değil mi?
Şunları kullanabilirsiniz NumberFormat#parse
:
try
{
NumberFormat.getInstance().parse(value);
}
catch(ParseException e)
{
// Not a number.
}
value
.
Android uygulamasını geliştirmek için java kullanıyorsanız, TextUtils.isDigitsOnly işlevini kullanabilirsiniz.
İşte benim sorunun cevabı.
Herhangi bir dizeyi herhangi bir ayrıştırıcı türü ile ayrıştırmak için kullanabileceğiniz tüm yakalama yöntemi isParsable(Object parser, String str)
. Ayrıştırıcı bir Class
veya bir olabilir object
. Bu ayrıca, yazdığınız özel ayrıştırıcıları kullanmanıza izin verir ve her zaman senaryo için çalışmalıdır, örneğin:
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");
İşte benim kod yöntem açıklamaları ile tamamlandı.
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;
}
}
Deneme yakalamadan kaçınmak ve negatif sayıları ve bilimsel gösterimi işlemek için iyi performans gösteren bir yaklaşım.
Pattern PATTERN = Pattern.compile( "^(-?0|-?[1-9]\\d*)(\\.\\d+)?(E\\d+)?$" );
public static boolean isNumeric( String value )
{
return value != null && PATTERN.matcher( value ).matches();
}
İşte bir dize sayısal olup olmadığını kontrol etmek için benim sınıf. Ayrıca sayısal dizeleri de düzeltir:
Hadi bakalım...
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;
}
}
Normal İfade Eşleme
Burada, daha fazla doğrulamayla yükseltilmiş "CraigTP" normal ifade eşleşmesinin başka bir örneği verilmiştir.
public static boolean isNumeric(String str)
{
return str.matches("^(?:(?:\\-{1})?\\d+(?:\\.{1}\\d+)?)$");
}
Normal İfade Testi
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
İstisnalar pahalıdır, ancak bu durumda RegEx çok daha uzun sürer. Aşağıdaki kod, biri istisnalar, diğeri regex kullanan iki fonksiyonun basit bir testini göstermektedir. Makinemde RegEx sürümü istisnadan 10 kat daha yavaş.
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);
}
}
// lütfen aşağıdaki kodu kontrol edin
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;
}
}
Bu kontrol için basit bir örnek:
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;
}
Java.util.Scanner nesnesini kullanabilirsiniz.
public static boolean isNumeric(String inputData) {
Scanner sc = new Scanner(inputData);
return sc.hasNextInt();
}
CraigTP'nin çözümünü bilimsel gösterimi ve nokta ve virgülleri ondalık ayırıcılar olarak kabul edecek şekilde değiştirdim
^-?\d+([,\.]\d+)?([eE]-?\d+)?$
misal
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
Bu yüzden .NET'te Try * yaklaşımını seviyorum. Java benzeri geleneksel Parse yöntemine ek olarak, bir TryParse yönteminiz de vardır. Java sözdiziminde (out parametreleri?) İyi değilim, bu yüzden lütfen bir tür sahte kod olarak aşağıdakileri ele alın. Yine de kavramı açıklığa kavuşturmalıdır.
boolean parseInteger(String s, out int number)
{
try {
number = Integer.parseInt(myString);
return true;
} catch(NumberFormatException e) {
return false;
}
}
Kullanımı:
int num;
if (parseInteger("23", out num)) {
// Do something with num.
}
Ayrıştırın (yani ile Integer#parseInt
) ve sadece istisnayı yakalayın. =)
Açıklığa kavuşturmak için: parseInt işlevi, herhangi bir durumda sayıyı ayrıştırabildiğini (açık bir şekilde) kontrol eder ve yine de ayrıştırmak istiyorsanız, gerçekten ayrıştırma yaparak herhangi bir performans atmayacaksınız.
Ayrıştırmak istemiyorsanız (ya da çok, çok nadiren ayrıştırmak istemiyorsanız) farklı bir şekilde yapmak isteyebilirsiniz.
Apache Commons Lang'dan NumberUtils.isCreatable () yöntemini kullanabilirsiniz .
NumberUtils.isNumber 4.0'da kullanımdan kaldırılacağından, bunun yerine NumberUtils.isCreatable () öğesini kullanın.
Java 8 Stream, lambda ifadesi, fonksiyonel arayüz
İşlenen tüm durumlar ( dize boş, dize boş vb. )
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();
Herhangi bir API kullanmadan sayıları ve ondalıkları kontrol etmek için bazı koşulları gösterdim,
Düzeltme Uzunluğunu Kontrol Edin 1 haneli sayı
Character.isDigit(char)
Sabit Uzunluk numarasını kontrol edin (Uzunluğun 6 olduğunu varsayın)
String number = "132452";
if(number.matches("([0-9]{6})"))
System.out.println("6 digits number identified");
Arasında Değişen Uzunluk sayısını kontrol edin (4 ila 6 uzunluk olduğunu varsayın)
// {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");
Değişen Uzunluk ondalık sayısını kontrol edin (4 ila 7 uzunluk olduğunu varsayın)
// 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");
Umarım herkese yardımcı olur.
Diğer cevaplara dayanarak kendi yazdım ve istisna kontrolü ile desen veya ayrıştırma kullanmıyor.
Maksimum bir eksi işaretini ve maksimum bir ondalık noktasını kontrol eder.
İşte bazı örnekler ve sonuçları:
"1", "-1", "-1,5" ve "-1,556" doğru değerini döndürür
"1..5", "1A.5", "1.5D", "-" ve "--1" yanlış döndürür
Not: Gerekirse bunu bir Locale parametresini kabul edecek şekilde değiştirebilir ve geçerli bir yerine belirli bir Yerel Ayar kullanmak için DecimalFormatSymbols.getInstance () çağrılarına iletebilirsiniz.
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;
}
İşte işe yarayabilecek iki yöntem. (İstisnalar kullanmadan). Not: Java varsayılan olarak bir by-pass değeridir ve bir String'in değeri, String'in nesne verilerinin adresidir. Yani, yaparken
stringNumber = stringNumber.replaceAll(" ", "");
Giriş değerini boşluk içermeyecek şekilde değiştirdiniz. İsterseniz bu satırı kaldırabilirsiniz.
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;
}
Burada şamandıralara izin vermek istiyorsanız başka bir yöntem Bu yöntem, formda sayıları 1.123,123,123,123,123.123 ben sadece yaptım geçmesine izin verdiği iddia ve çalıştığından emin olmak için daha fazla test gerektiğini düşünüyorum.
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;
}