Sie können auch verwenden, StringUtils.isNumericSpacewas truefür leere Zeichenfolgen zurückgibt und interne Leerzeichen in der Zeichenfolge ignoriert. Eine andere Möglichkeit ist die Verwendung, bei NumberUtils.isParsableder grundsätzlich überprüft wird, ob die Nummer gemäß Java analysiert werden kann. (Die verknüpften Javadocs enthalten detaillierte Beispiele für jede Methode.)
StringUtils.isNumeric()wahrscheinlich wäre dies hier nicht angebracht, da nur geprüft wird, ob die Zeichenfolge eine Folge von Ziffern ist. Wäre in Ordnung für die meisten Ints, aber nicht für Zahlen mit Dezimalstellen, Gruppentrennzeichen usw.
Jeff Mercado
42
Erfinden Sie das Rad neu, weil Sie keine ganze Bibliothek einschließen, weil Sie eine 3-Zeilen-Funktion an einer Stelle benötigen.
Dalvarezmartinez1
12
Lohnt es sich wirklich, eine ganze Bibliothek für diese Funktion hinzuzufügen ? Natürlich, wenn es mit anderen Dingen verwendet wird, ist das großartig, aber es ist wahrscheinlich übertrieben, wenn man bedenkt, dass die Leute dies in einer Codezeile gelöst haben.
Wasser
7
Funktioniert nicht mit Negativen. Und die Hälfte aller Zahlen ist negativ, also .....
Paul Draper
6
@PaulDraper: Sie haben Recht, StringUtilsunterstützt keine führenden Zeichen, aber Sie sollten überprüfen NumberUtils.isCreatable, es unterstützt Negative richtig.
Palacsint
904
Dies erfolgt in der Regel mit einer einfachen benutzerdefinierten Funktion (dh Roll-Your-Own-Funktion "isNumeric").
Wenn Sie diese Funktion jedoch häufig aufrufen und erwarten, dass viele der Überprüfungen fehlschlagen, weil sie keine Zahl sind, ist die Leistung dieses Mechanismus nicht besonders gut, da Sie sich darauf verlassen, dass für jeden Fehler Ausnahmen ausgelöst werden. Das ist eine ziemlich teure Operation.
Ein alternativer Ansatz kann darin bestehen, einen regulären Ausdruck zu verwenden, um die Gültigkeit einer Zahl zu überprüfen:
publicstaticboolean isNumeric(String str){return str.matches("-?\\d+(\\.\\d+)?");//match a number with optional '-' and decimal.}
Seien Sie jedoch vorsichtig mit dem oben genannten RegEx-Mechanismus, da er fehlschlägt, wenn Sie nicht-arabische Ziffern verwenden (dh andere Ziffern als 0 bis 9). Dies liegt daran, dass der "\ d" -Teil des RegEx nur mit [0-9] übereinstimmt und international nicht numerisch bekannt ist. (Vielen Dank an OregonGhost für diesen Hinweis!)
Oder eine andere Alternative ist die Verwendung des in Java integrierten Objekts java.text.NumberFormat, um festzustellen, ob sich die Parserposition nach dem Parsen der Zeichenfolge am Ende der Zeichenfolge befindet. Wenn dies der Fall ist, können wir davon ausgehen, dass die gesamte Zeichenfolge numerisch ist:
Stimmt \ d in Java Regex nur mit lateinischen Ziffern überein? Wenn es sich um .NET-Regexe handelt, treten Probleme mit anderen (z. B. arabischen) Ziffern auf, wie hier erläutert: blogs.msdn.com/oldnewthing/archive/2004/03/09/86555.aspx
OregonGhost
3
Die numberFormatter-Lösung ist wahrscheinlich nur unwesentlich besser als die NumberFormatException-Lösung. Ich vermute, der beste Weg ist, Regex eins zu verwenden.
Chii
11
Beachten Sie, dass der .in Ihrer Regex angegebene Wert mit jedem Zeichen übereinstimmt, nicht nur mit dem Dezimaltrennzeichen.
jqno
9
+1 für die Realisierung der Kosten für Versuch / Fang. Dies ist eigentlich ein schrecklicher Ansatz, der auf lange Sicht für die wiederholte Verwendung verwendet werden muss, aber in Java bleiben wir wirklich dabei.
Demongolem
5
Beachten Sie, dass es keine "lateinischen Ziffern" gibt und die Ziffern 0-9 tatsächlich arabische Ziffern sind. Die Leute sind wahrscheinlich mit römischen Ziffern vertraut, die von Leuten verwendet wurden, die Latein sprachen, in der Form I, II, III, IV, V, VI usw. en.wikipedia.org/wiki/Arabic_numerals ; en.wikipedia.org/wiki/Roman_numerals
@ kape123 :) sicher, dass "123.456" keine Ziffern enthält.
Ahmed Alejo
8
Hinweis: Dies führt zu NPE für die Null-Eingabe. Funktioniert auch nicht mit negativen Zahlen oder Dezimalstellen.
gMale
2
Ich mag das!! Ich denke, das ist absolut für Ziffern. Nicht für .,-
IllusionJJ
Das ist genau das, wonach ich gesucht habe. Etwas Einfaches, um nur nach den Ziffern 0-9 zu suchen. Ich habe einen Filter in der Deklaration meines EditText festgelegt, aber nur für den Fall, dass dieser später geändert oder ersetzt wird, ist es schön, auch eine einfache programmatische Überprüfung durchzuführen.
Sie können auch eine Methodenreferenz verwenden: someString.chars (). AllMatch (Character :: isDigit)
Wienczny
3
Schön, aber es erfindet das Rad immer noch neu, wie fast alle "Lösungen" hier. Scheitert auch bei 'null' (wie fast alle anderen).
Qben
8
Diese Antwort ist kurz, einfach und lesbar. Sie können es fast wie Englisch lesen - "Zeichen alle übereinstimmen Ziffern". Es sind keine Bibliotheken von Drittanbietern erforderlich. In nicht außergewöhnlichen Fällen werden keine Ausnahmen verwendet. Dies sollte die akzeptierte Antwort werden.
Andy Thomas
14
Was wird es für "-1" produzieren?
Balázs Németh
2
Nicht die richtige Antwort. Eine numerische Zeichenfolge kann nicht numerische Zeichen (z. B. "." Oder "-") enthalten und dennoch perfekt numerisch sein. Zum Beispiel schlagen 0,5, -1 und 1.000 mit dieser Antwort fehl und sind dennoch perfekt numerisch.
Simeon G
125
Wie @CraigTP in seiner hervorragenden Antwort erwähnt hatte, habe ich ähnliche Leistungsprobleme bei der Verwendung von Ausnahmen, um zu testen, ob die Zeichenfolge numerisch ist oder nicht. Also spalte ich den String und benutze ihn java.lang.Character.isDigit().
publicstaticboolean isNumeric(String str){for(char c : str.toCharArray()){if(!Character.isDigit(c))returnfalse;}returntrue;}
Nach dem Javadoc , Character.isDigit(char)wird richtig erkennt nicht-lateinische Ziffern. In Bezug auf die Leistung denke ich, dass eine einfache Anzahl von N Vergleichen, bei denen N die Anzahl der Zeichen in der Zeichenfolge ist, rechnerisch effizienter wäre als ein Regex-Abgleich.
UPDATE: Wie von Jean-François Corbett im Kommentar ausgeführt, würde der obige Code nur positive ganze Zahlen validieren, was den Großteil meines Anwendungsfalls abdeckt. Im Folgenden finden Sie den aktualisierten Code, mit dem Dezimalzahlen gemäß dem in Ihrem System verwendeten Standardgebietsschema korrekt überprüft werden. Dabei wird davon ausgegangen, dass das Dezimaltrennzeichen nur einmal in der Zeichenfolge vorkommt.
publicstaticboolean isStringNumeric(String str ){DecimalFormatSymbols currentLocaleSymbols =DecimalFormatSymbols.getInstance();char localeMinusSign = currentLocaleSymbols.getMinusSign();if(!Character.isDigit( str.charAt(0))&& str.charAt(0)!= localeMinusSign )returnfalse;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;}returnfalse;}}returntrue;}
Wird das Dezimaltrennzeichen nicht auch dazu führen, dass dies fehlschlägt?
Jean-François Corbett
1
@ Jean-FrançoisCorbett: Guter Punkt, ich habe den Code mit einem neueren Code aktualisiert, der Dezimaltrennzeichen akzeptiert.
Ibrahim Arief
2
Fehlschlägt -ve sign diese Funktion?
Java_Maus
3
Durch Aufrufen toCharArray()wird eine Kopie des Arrays im String-Objekt erstellt, da Strings unveränderlich sind. Wahrscheinlich schneller, um die charAt(int index)Methode direkt für das String-Objekt zu verwenden.
Mike Kucera
2
Wird generiert, StringIndexOutOfBoundsExceptionwenn eine Zeichenfolge mit der Länge 0 übergeben wird. Kann mitif(str.length() == 0) return false;
samgak
43
Die Guava-Bibliothek von Google bietet hierfür eine nützliche Hilfsmethode : Ints.tryParse. Sie verwenden es wie, Integer.parseIntaber es gibt zurück, nullanstatt eine Ausnahme auszulösen, wenn die Zeichenfolge nicht auf eine gültige Ganzzahl analysiert wird. Beachten Sie, dass Integer und nicht int zurückgegeben wird. Sie müssen es also zurück in int konvertieren / autoboxen.
Ab der aktuellen Version - Guava r11 - ist es jedoch immer noch mit @Beta gekennzeichnet.
Ich habe es nicht bewertet. Wenn man sich den Quellcode ansieht, entsteht ein gewisser Aufwand durch viele Überprüfungen Character.digit(string.charAt(idx))der geistigen Gesundheit , aber am Ende verwenden sie die Antwort von @Ibrahim oben, ähnlich, aber etwas anders. Es gibt keine Ausnahmebehandlung bei der Implementierung.
Die akzeptierte Antwort, drei Jahre zuvor, wurde bereits behandelt Number.isNumber().
Andy Thomas
Das glaube ich nicht. Es wurde die akzeptierte Antwort aktualisiert oder geändert. Ich erinnere mich, dass die akzeptierte Antwort NumberUtils nicht abdeckte, deshalb habe ich meine Antwort hinzugefügt. Aber danke für den Kommentar
Goot
2
@Goot - Der Verlauf der akzeptierten Antwort zeigt, dass Number.isNumber()ab der ersten Version der Antwort vom 24. September 12 um 17:01 Uhr vorhanden war.
Andy Thomas
@Goot, das ist ziemlich gut, da es im Gegensatz zu StringUtils auch die Dezimalwertprüfung abdeckt.
Heena Hussain
24
Warum drängen alle auf Ausnahme- / Regex-Lösungen?
Ich kann zwar verstehen, dass die meisten Leute mit try / catch gut zurechtkommen, aber wenn Sie es häufig tun möchten, kann es extrem anstrengend sein.
Was ich hier getan habe, war die Verwendung des regulären Ausdrucks, der parseNumber () -Methoden und der Array-Suchmethode, um festzustellen, welche die effizienteste war. Dieses Mal habe ich nur ganzzahlige Zahlen betrachtet.
publicstaticboolean isNumericRegex(String str){if(str ==null)returnfalse;return str.matches("-?\\d+");}publicstaticboolean isNumericArray(String str){if(str ==null)returnfalse;char[] data = str.toCharArray();if(data.length <=0)returnfalse;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.returnfalse;}returntrue;}publicstaticboolean isNumericException(String str){if(str ==null)returnfalse;try{/* int i = */Integer.parseInt(str);}catch(NumberFormatException nfe){returnfalse;}returntrue;}
Die Ergebnisse in Geschwindigkeit, die ich bekam, waren:
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 signArray 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]Withnull: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
Haftungsausschluss: Ich behaupte nicht, dass diese Methoden zu 100% optimiert sind, sondern nur zur Demonstration der Daten
Ausnahmen wurden nur dann gewonnen, wenn die Zahl 4 Zeichen oder weniger beträgt und jede Zeichenfolge immer eine Zahl ist. In welchem Fall sollte überhaupt ein Scheck ausgestellt werden?
Kurz gesagt, es ist äußerst schmerzhaft, wenn Sie beim Versuch / Fang häufig auf ungültige Zahlen stoßen, was Sinn macht. Eine wichtige Regel, die ich immer befolge, ist, NIEMALS try / catch für den Programmfluss zu verwenden . Dies ist ein Beispiel dafür.
Interessanterweise ist das einfache if char <0 || > 9 war extrem einfach zu schreiben, leicht zu merken (und sollte in mehreren Sprachen funktionieren) und gewinnt fast alle Testszenarien.
Der einzige Nachteil ist, dass Integer.parseInt () möglicherweise Nicht-ASCII-Zahlen verarbeitet, während dies bei der Array-Suchmethode nicht der Fall ist.
Für diejenigen, die sich fragen, warum ich gesagt habe, dass es einfach ist, sich an das Zeichenarray zu erinnern. Wenn Sie wissen, dass es keine negativen Vorzeichen gibt, können Sie leicht mit etwas davonkommen, das sich wie folgt verdichtet:
publicstaticboolean isNumericArray(String str){if(str ==null)returnfalse;for(char c : str.toCharArray())if(c <'0'|| c >'9')returnfalse;returntrue;
Abschließend war ich neugierig auf den Zuweisungsoperator im akzeptierten Beispiel mit allen abgegebenen Stimmen. Hinzufügen in der Zuordnung von
double d =Double.parseDouble(...)
ist nicht nur nutzlos, da Sie den Wert nicht einmal verwenden, sondern verschwendet auch Verarbeitungszeit und erhöht die Laufzeit um einige Nanosekunden (was zu einer Erhöhung der Tests um 100 bis 200 ms führte). Ich kann nicht verstehen, warum das jemand tun würde, da es tatsächlich zusätzliche Arbeit ist, um die Leistung zu reduzieren.
Sie würden denken, das wäre optimiert ... obwohl ich vielleicht den Bytecode überprüfen und sehen sollte, was der Compiler tut. Das erklärt nicht, warum es für mich immer länger war, wenn es irgendwie optimiert ist ... deshalb frage ich mich, was los ist. Als Hinweis: Mit länger meine ich, den Test für 10000000 Iterationen auszuführen und dieses Programm mehrmals (10x +) auszuführen, hat immer gezeigt, dass es langsamer ist.
BEARBEITEN: Ein Test für Character.isDigit () wurde aktualisiert.
Kompiliert dies nicht jedes Mal einen neuen regulären Ausdruck? Das scheint nicht sehr effizient zu sein.
Samuel Edwin Ward
1
@SamuelEdwinWard Das ist der ganze Grund, warum ich diesen Beitrag verfasst habe ... Das Regex-Beispiel verwendete die Antworten anderer Leute und zeigte, wie ineffizient es ist. Selbst wenn Sie versuchen, Regex zu erstellen, indem Sie es vorab kompilieren und nur verwenden, betragen die Zeitunterschiede: 2587 ms für den Regex, den ich von anderen bereitgestellten Personen gepostet habe, 950 ms, wenn er vorab kompiliert wurde, 144 ms, wenn Sie ihn als ausführen numerisches Array (für 1-mil-Iterationen derselben Zeichenfolge). Vorab zu kompilieren würde natürlich helfen, aber leider ist es dem Array-Weg immer noch ziemlich unterlegen ... es sei denn, es gibt eine verrückte Optimierung, von der ich nichts weiß.
Wasser
Zu glauben, dass Regex die Dinge schneller macht, ist fast ein Trugschluss. Wenn es eine einmalige Suche ist, ja, ich verstehe ... aber ich habe festgestellt, dass effizient geschriebener Code Regex tatsächlich genug übertrifft, um Sie zu schockieren! Großartiger Beitrag @Water
Der reguläre Ausdruck von CraigTP (siehe oben) führt zu einigen falsch positiven Ergebnissen. ZB "23y4" wird als Zahl gezählt, weil '.' Entspricht einem beliebigen Zeichen, das nicht dem Dezimalpunkt entspricht.
Außerdem wird jede Zahl mit einem führenden '+' abgelehnt.
Eine Alternative, die diese beiden kleinen Probleme vermeidet, ist
Dies wird truefür ein einzelnes Plus "+"oder Minus "-"und falsefür"0."
user85421
Guter Fang für das einzelne Plus oder Minus. Ist "0". eine gültige Nummer?
user872985
"0."ist gültig für Double.parseDouble()und ist ein gültiges Literal gemäß JLS ( §3.10.2 )!
user85421
Das Erstellen regulärer Ausdrücke ist ebenfalls kostspielig. Der reguläre Ausdruck muss einmal erstellt und wiederverwendet werden
Daniel Nuriyev
1
Sie sollten es ändern inmatches("-?\\d+([.]\\d+)?")
Bobs
14
Wir können versuchen, alle Zahlen aus der angegebenen Zeichenfolge durch ("") zu ersetzen, dh ein Leerzeichen. Wenn danach die Länge der Zeichenfolge Null ist, können wir sagen, dass die angegebene Zeichenfolge nur Zahlen enthält. [Wenn Sie diese Antwort hilfreich fanden, ziehen Sie bitte eine Abstimmung in Betracht] Beispiel:
boolean isNumber(String str){if(str.length()==0)returnfalse;//To check if string is emptyif(str.charAt(0)=='-')
str = str.replaceFirst("-","");// for handling -ve numbersSystem.out.println(str);
str = str.replaceFirst("\\.","");//to check if it contains more than one decimal pointsif(str.length()==0)returnfalse;// to check if it is empty string after removing -ve sign and decimal pointSystem.out.println(str);return str.replaceAll("[0-9]","").length()==0;}
Offensichtlich gilt dies nicht für alle Zahlenformen, aber hier ist eine Gegenstimme für ein anderes Denken ... wenn der ursprüngliche Gedanke dein war, das heißt.
Eine Catch-All-Convenience-Methode, mit der Sie einen beliebigen String mit einem beliebigen Parsertyp analysieren können : isParsable(Object parser, String str). Der Parser kann ein Classoder ein sein object. Auf diese Weise können Sie auch benutzerdefinierte Parser verwenden, die Sie geschrieben haben und die für jedes Szenario funktionieren sollten, z.
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");
Hier ist mein Code mit Methodenbeschreibungen.
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
*/publicstaticboolean isParsable(Object parser,String str){Class theClass =(parser instanceofClass?(Class)parser: parser.getClass());boolean staticOnly =(parser == theClass), foundAtLeastOne =false;Method[] methods = theClass.getMethods();// Loop over methodsfor(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);returntrue;// 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 methodcontinue;// Look for other parse methods}}}// No more accessible parse method could be found.if(foundAtLeastOne)returnfalse;elsethrownewRuntimeException(newNoSuchMethodException());}/**
* 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
*/publicstaticboolean willParse(Object parser,String str){try{return isParsable(parser, str);}catch(Throwable exception){returnfalse;}}
Ein leistungsfähiger Ansatz, der das Fangen von Versuchen vermeidet und mit negativen Zahlen und wissenschaftlicher Notation umgeht.
Pattern PATTERN =Pattern.compile("^(-?0|-?[1-9]\\d*)(\\.\\d+)?(E\\d+)?$");publicstaticboolean isNumeric(String value ){return value !=null&& PATTERN.matcher( value ).matches();}
Entfernt mehrere Punkte ["-12.0.20.000" -> "-12.02"]
Keine zusätzlichen Bibliotheken, nur Standard-Java
Bitte schön...
publicclassNumUtils{/**
* Transforms a string to an integer. If no numerical chars returns a String "0".
*
* @param str
* @return retStr
*/staticString 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
*/staticString makeToDouble(String str){Boolean dotWasFound =false;String orgStr = str;String retStr;int firstDotPos =0;Boolean negative =false;//check if str is nullif(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 dotsfor(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 beginingdouble 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;}staticboolean isNumeric(String str){try{double d =Double.parseDouble(str);}catch(NumberFormatException nfe){returnfalse;}returntrue;}}
Ausnahmen sind teuer, aber in diesem Fall dauert der RegEx viel länger. Der folgende Code zeigt einen einfachen Test von zwei Funktionen - eine mit Ausnahmen und eine mit Regex. Auf meinem Computer ist die RegEx-Version zehnmal langsamer als die Ausnahme.
import java.util.Date;publicclassIsNumeric{publicstaticboolean isNumericOne(String s){return s.matches("-?\\d+(\\.\\d+)?");//match a number with optional '-' and decimal. }publicstaticboolean isNumericTwo(String s){try{Double.parseDouble(s);returntrue;}catch(Exception e){returnfalse;}}publicstaticvoid main(String[] args){String test ="12345.F";long before =newDate().getTime();for(int x=0;x<1000000;++x){//isNumericTwo(test);
isNumericOne(test);}long after =newDate().getTime();System.out.println(after-before);}}
Im Allgemeinen denke ich, dass diese Art von Code verwendet wird, um Dinge wie eingegebene Eingaben zu überprüfen. In diesem Fall spielt Geschwindigkeit keine Rolle, und es ist falsch, etwas so Hässliches zu tun, als eine Ausnahme auszulösen, um nach Nummern oder Nicht-Nummern zu suchen.
user872985
Vielleicht nicht. Die eingegebene Eingabe wird im Allgemeinen von der UI-Komponente überprüft, wobei Fehler sofort angezeigt werden können, bevor der Wert gesendet wird. Es ist möglicherweise üblicher, Zeichenfolgen aus großen Eingabetextdateien zu überprüfen - wo es auf die Leistung ankommt. Das Ziel meiner Antwort hier ist es, die Aussage "Ausnahmen sind langsam" in der akzeptierten Antwort anzusprechen. Komplexer Regex ist viel teurer. Und es gibt überhaupt keinen "hässlichen Wurf" in meinem Code - nur eine schnellere Möglichkeit, Verstöße zu erkennen. Mit einem Check-First-Then-Calculate-Ansatz führen Sie zwei Durchgänge durch die Eingabe durch: einen zum Überprüfen und einen zum Konvertieren.
ChrisCantrell
5
// Bitte überprüfen Sie den folgenden Code
publicstaticboolean isDigitsOnly(CharSequence str){finalint len = str.length();for(int i =0; i < len; i++){if(!Character.isDigit(str.charAt(i))){returnfalse;}}returntrue;}
Die Frage lautet "numerisch" und kann nicht ganzzahlige Werte enthalten.
rghome
3
// only intpublicstaticboolean isNumber(int num){return(num >=48&& c <=57);// 0 - 9}// is type of number including . - e E publicstaticboolean 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 publicstaticboolean 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;}publicstaticboolean isNumeric(String s){try{Double.parseDouble(s);returntrue;}catch(Exception e){returnfalse;}}
Dies ist ein einfaches Beispiel für diese Prüfung:
publicstaticboolean 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;}
Ich habe die Lösung von CraigTP so geändert, dass auch die wissenschaftliche Notation sowie Punkt und Komma als Dezimaltrennzeichen akzeptiert werden
^-?\d+([,\.]\d+)?([eE]-?\d+)?$
Beispiel
var re =newRegExp("^-?\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
Deshalb mag ich den Try * -Ansatz in .NET. Zusätzlich zu der traditionellen Parse-Methode, die der Java-Methode ähnelt, gibt es auch eine TryParse-Methode. Ich bin nicht gut in der Java-Syntax (out-Parameter?), Behandeln Sie daher Folgendes als eine Art Pseudocode. Es sollte das Konzept jedoch klar machen.
boolean parseInteger(String s, out int number){try{
number =Integer.parseInt(myString);returntrue;}catch(NumberFormatException e){returnfalse;}}
Verwendungszweck:
int num;if(parseInteger("23", out num)){// Do something with num.}
Ja, es gibt keine "out-Parameter" in Java. Da der Integer-Wrapper unveränderlich ist (daher nicht als gültige Referenz zum Speichern der Ausgabe verwendet werden kann), besteht die sinnvolle idiomatische Option darin, ein Integer-Objekt zurückzugeben, das bei der Analyse null sein könnte gescheitert. Eine hässlichere Option könnte darin bestehen, ein int [1] als Ausgabeparameter zu übergeben.
Fortan
Ja, ich erinnere mich an eine Diskussion darüber, warum Java keine Ausgabeparameter hat. Aber die Rückgabe einer Ganzzahl (bei Bedarf als Null) wäre auch in Ordnung, obwohl ich nichts über die Leistung von Java in Bezug auf das Boxen / Entpacken weiß.
OregonGhost
4
Ich mag C # genauso wie der nächste Typ, aber es nützt nichts, ein .NET C # -Code-Snippet für eine Java-Frage hinzuzufügen, wenn die Funktionen in Java nicht vorhanden sind
Shane
Es würde ein
Sonarproblem verursachen,
2
Analysieren Sie es (dh mit Integer#parseInt) und fangen Sie einfach die Ausnahme ab. =)
Zur Verdeutlichung: Die Funktion parseInt prüft, ob sie die Nummer auf jeden Fall (offensichtlich) analysieren kann, und wenn Sie sie trotzdem analysieren möchten, werden Sie keinen Leistungseinbruch erleiden, wenn Sie die Analyse tatsächlich durchführen.
Wenn Sie es nicht analysieren möchten (oder sehr, sehr selten analysieren möchten), möchten Sie es natürlich natürlich anders machen.
Ich habe einige Bedingungen dargestellt, um Zahlen und Dezimalstellen ohne Verwendung einer API zu überprüfen.
Überprüfen Sie die 1-stellige Nummer der Fixlänge
Character.isDigit(char)
Überprüfen Sie die Nummer der festen Länge (Angenommen, die Länge beträgt 6).
String number ="132452";if(number.matches("([0-9]{6})"))System.out.println("6 digits number identified");
Überprüfen Sie die Anzahl der unterschiedlichen Längen zwischen (Nehmen Sie eine Länge von 4 bis 6 an).
// {n,m} n <= length <= mString 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");
Überprüfen Sie die Dezimalzahl für die unterschiedliche Länge zwischen (Annahme einer Länge von 4 bis 7).
// It will not count the '.' (Period) in lengthString 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");
Basierend auf anderen Antworten habe ich meine eigenen geschrieben und es werden keine Muster oder Parsing mit Ausnahmeprüfung verwendet.
Es wird auf maximal ein Minuszeichen und auf maximal einen Dezimalpunkt geprüft.
Hier einige Beispiele und deren Ergebnisse:
"1", "-1", "-1,5" und "-1,556" geben true zurück
"1..5", "1A.5", "1.5D", "-" und "--1" geben false zurück
Hinweis: Bei Bedarf können Sie dies ändern, um einen Locale-Parameter zu akzeptieren und diesen an die DecimalFormatSymbols.getInstance () -Aufrufe zu übergeben, um ein bestimmtes Gebietsschema anstelle des aktuellen zu verwenden.
publicstaticboolean isNumeric(finalString input){//Check for null or blank stringif(input ==null|| input.isBlank())returnfalse;//Retrieve the minus sign and decimal separator characters from the current Localefinal var localeMinusSign =DecimalFormatSymbols.getInstance().getMinusSign();final var localeDecimalSeparator =DecimalFormatSymbols.getInstance().getDecimalSeparator();//Check if first character is a minus signfinal var isNegative = input.charAt(0)== localeMinusSign;//Check if string is not just a minus signif(isNegative && input.length()==1)returnfalse;
var isDecimalSeparatorFound =false;//If the string has a minus sign ignore the first characterfinal 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 separatorfor(var i = startCharIndex; i < input.length(); i++){if(!Character.isDigit(input.charAt(i))){if(input.charAt(i)== localeDecimalSeparator &&!isDecimalSeparatorFound){
isDecimalSeparatorFound =true;}elsereturnfalse;}}returntrue;}
Hier sind zwei Methoden, die funktionieren könnten. (Ohne Ausnahmen zu verwenden). Hinweis: Java ist standardmäßig ein Pass-by-Wert, und der Wert eines Strings ist die Adresse der Objektdaten des Strings. Also, wenn du es tust
stringNumber = stringNumber.replaceAll(" ","");
Sie haben den Eingabewert so geändert, dass keine Leerzeichen mehr vorhanden sind. Sie können diese Zeile entfernen, wenn Sie möchten.
Hier ist eine andere Methode für den Fall, dass Sie Floats zulassen möchten. Diese Methode erlaubt angeblich, dass Zahlen in der Form 1.123.123.123.123.123.123 übergeben. Ich habe es gerade gemacht, und ich denke, es müssen weitere Tests durchgeführt werden, um sicherzustellen, dass es funktioniert.
privateboolean isValidStringTrueNumber(String stringNumber){if(stringNumber.isEmpty()){returnfalse;}
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)){returnfalse;}if(!Character.isDigit(charNumber[i]))//Char is not a digit.{if(charNumber[i]==','){if(decimalPointPassed){returnfalse;}
commaFound =true;//check that next three chars are only digits.
commaCounter +=3;}elseif(charNumber[i]=='.'){
decimalPointPassed =true;
countOfDecimalPoint++;}else{returnfalse;}}else//Char is a digit.{if((commaCounter>=0)&&(commaFound)){if(!decimalPointPassed){
commaCounter--;}}if(!commaFound){
countOfDigitsBeforeFirstComma++;}if(!decimalPointPassed){
countOfDigitsBeforeDecimalPoint++;}else{
countOfDigitsAfterDecimalPoint++;}}}if((commaFound)&&(countOfDigitsBeforeFirstComma>3)){returnfalse;}if(countOfDecimalPoint>1){returnfalse;}if((decimalPointPassed)&&((countOfDigitsBeforeDecimalPoint==0)||(countOfDigitsAfterDecimalPoint==0))){returnfalse;}returntrue;}
Oh, gute Frage. Ich denke, dass dies nur normale Ganzzahlen funktioniert. Die Methode wurde ursprünglich erstellt, um eingegebene Telefonnummern zu filtern und Nummern zu zählen.
Integer.parseInt()
Mobiltelefonnummern nicht analysiert werdenNumberFormatException
.Antworten:
Mit Apache Commons Lang 3.5 und höher:
NumberUtils.isCreatable
oderStringUtils.isNumeric
.Mit Apache Commons Lang 3.4 und darunter:
NumberUtils.isNumber
oderStringUtils.isNumeric
.Sie können auch verwenden,
StringUtils.isNumericSpace
wastrue
für leere Zeichenfolgen zurückgibt und interne Leerzeichen in der Zeichenfolge ignoriert. Eine andere Möglichkeit ist die Verwendung, beiNumberUtils.isParsable
der grundsätzlich überprüft wird, ob die Nummer gemäß Java analysiert werden kann. (Die verknüpften Javadocs enthalten detaillierte Beispiele für jede Methode.)quelle
StringUtils.isNumeric()
wahrscheinlich wäre dies hier nicht angebracht, da nur geprüft wird, ob die Zeichenfolge eine Folge von Ziffern ist. Wäre in Ordnung für die meisten Ints, aber nicht für Zahlen mit Dezimalstellen, Gruppentrennzeichen usw.StringUtils
unterstützt keine führenden Zeichen, aber Sie sollten überprüfenNumberUtils.isCreatable
, es unterstützt Negative richtig.Dies erfolgt in der Regel mit einer einfachen benutzerdefinierten Funktion (dh Roll-Your-Own-Funktion "isNumeric").
Etwas wie:
Wenn Sie diese Funktion jedoch häufig aufrufen und erwarten, dass viele der Überprüfungen fehlschlagen, weil sie keine Zahl sind, ist die Leistung dieses Mechanismus nicht besonders gut, da Sie sich darauf verlassen, dass für jeden Fehler Ausnahmen ausgelöst werden. Das ist eine ziemlich teure Operation.
Ein alternativer Ansatz kann darin bestehen, einen regulären Ausdruck zu verwenden, um die Gültigkeit einer Zahl zu überprüfen:
Seien Sie jedoch vorsichtig mit dem oben genannten RegEx-Mechanismus, da er fehlschlägt, wenn Sie nicht-arabische Ziffern verwenden (dh andere Ziffern als 0 bis 9). Dies liegt daran, dass der "\ d" -Teil des RegEx nur mit [0-9] übereinstimmt und international nicht numerisch bekannt ist. (Vielen Dank an OregonGhost für diesen Hinweis!)
Oder eine andere Alternative ist die Verwendung des in Java integrierten Objekts java.text.NumberFormat, um festzustellen, ob sich die Parserposition nach dem Parsen der Zeichenfolge am Ende der Zeichenfolge befindet. Wenn dies der Fall ist, können wir davon ausgehen, dass die gesamte Zeichenfolge numerisch ist:
quelle
.
in Ihrer Regex angegebene Wert mit jedem Zeichen übereinstimmt, nicht nur mit dem Dezimaltrennzeichen.Wenn Sie auf Android sind, sollten Sie verwenden:
Dokumentation finden Sie hier
halte es einfach . Meist kann jeder "neu programmieren" (das Gleiche).
quelle
.
,-
Java 8 Lambda-Ausdrücke.
quelle
Wie @CraigTP in seiner hervorragenden Antwort erwähnt hatte, habe ich ähnliche Leistungsprobleme bei der Verwendung von Ausnahmen, um zu testen, ob die Zeichenfolge numerisch ist oder nicht. Also spalte ich den String und benutze ihn
java.lang.Character.isDigit()
.Nach dem Javadoc ,
Character.isDigit(char)
wird richtig erkennt nicht-lateinische Ziffern. In Bezug auf die Leistung denke ich, dass eine einfache Anzahl von N Vergleichen, bei denen N die Anzahl der Zeichen in der Zeichenfolge ist, rechnerisch effizienter wäre als ein Regex-Abgleich.UPDATE: Wie von Jean-François Corbett im Kommentar ausgeführt, würde der obige Code nur positive ganze Zahlen validieren, was den Großteil meines Anwendungsfalls abdeckt. Im Folgenden finden Sie den aktualisierten Code, mit dem Dezimalzahlen gemäß dem in Ihrem System verwendeten Standardgebietsschema korrekt überprüft werden. Dabei wird davon ausgegangen, dass das Dezimaltrennzeichen nur einmal in der Zeichenfolge vorkommt.
quelle
toCharArray()
wird eine Kopie des Arrays im String-Objekt erstellt, da Strings unveränderlich sind. Wahrscheinlich schneller, um diecharAt(int index)
Methode direkt für das String-Objekt zu verwenden.StringIndexOutOfBoundsException
wenn eine Zeichenfolge mit der Länge 0 übergeben wird. Kann mitif(str.length() == 0) return false;
Die Guava-Bibliothek von Google bietet hierfür eine nützliche Hilfsmethode :
Ints.tryParse
. Sie verwenden es wie,Integer.parseInt
aber es gibt zurück,null
anstatt eine Ausnahme auszulösen, wenn die Zeichenfolge nicht auf eine gültige Ganzzahl analysiert wird. Beachten Sie, dass Integer und nicht int zurückgegeben wird. Sie müssen es also zurück in int konvertieren / autoboxen.Beispiel:
Ab der aktuellen Version - Guava r11 - ist es jedoch immer noch mit @Beta gekennzeichnet.
Ich habe es nicht bewertet. Wenn man sich den Quellcode ansieht, entsteht ein gewisser Aufwand durch viele Überprüfungen
Character.digit(string.charAt(idx))
der geistigen Gesundheit , aber am Ende verwenden sie die Antwort von @Ibrahim oben, ähnlich, aber etwas anders. Es gibt keine Ausnahmebehandlung bei der Implementierung.quelle
Verwenden Sie keine Ausnahmen, um Ihre Werte zu überprüfen. Verwenden Sie stattdessen Util-Bibliotheken wie Apache NumberUtils:
Bearbeiten :
Bitte beachten Sie, dass NumberUtils Ihren Wert als hexadezimal interpretiert, wenn Ihre Zeichenfolge mit einer 0 beginnt.
quelle
Number.isNumber()
.Number.isNumber()
ab der ersten Version der Antwort vom 24. September 12 um 17:01 Uhr vorhanden war.Warum drängen alle auf Ausnahme- / Regex-Lösungen?
Ich kann zwar verstehen, dass die meisten Leute mit try / catch gut zurechtkommen, aber wenn Sie es häufig tun möchten, kann es extrem anstrengend sein.
Was ich hier getan habe, war die Verwendung des regulären Ausdrucks, der parseNumber () -Methoden und der Array-Suchmethode, um festzustellen, welche die effizienteste war. Dieses Mal habe ich nur ganzzahlige Zahlen betrachtet.
Die Ergebnisse in Geschwindigkeit, die ich bekam, waren:
Haftungsausschluss: Ich behaupte nicht, dass diese Methoden zu 100% optimiert sind, sondern nur zur Demonstration der Daten
Ausnahmen wurden nur dann gewonnen, wenn die Zahl 4 Zeichen oder weniger beträgt und jede Zeichenfolge immer eine Zahl ist. In welchem Fall sollte überhaupt ein Scheck ausgestellt werden?
Kurz gesagt, es ist äußerst schmerzhaft, wenn Sie beim Versuch / Fang häufig auf ungültige Zahlen stoßen, was Sinn macht. Eine wichtige Regel, die ich immer befolge, ist, NIEMALS try / catch für den Programmfluss zu verwenden . Dies ist ein Beispiel dafür.
Interessanterweise ist das einfache if char <0 || > 9 war extrem einfach zu schreiben, leicht zu merken (und sollte in mehreren Sprachen funktionieren) und gewinnt fast alle Testszenarien.
Der einzige Nachteil ist, dass Integer.parseInt () möglicherweise Nicht-ASCII-Zahlen verarbeitet, während dies bei der Array-Suchmethode nicht der Fall ist.
Für diejenigen, die sich fragen, warum ich gesagt habe, dass es einfach ist, sich an das Zeichenarray zu erinnern. Wenn Sie wissen, dass es keine negativen Vorzeichen gibt, können Sie leicht mit etwas davonkommen, das sich wie folgt verdichtet:
Abschließend war ich neugierig auf den Zuweisungsoperator im akzeptierten Beispiel mit allen abgegebenen Stimmen. Hinzufügen in der Zuordnung von
ist nicht nur nutzlos, da Sie den Wert nicht einmal verwenden, sondern verschwendet auch Verarbeitungszeit und erhöht die Laufzeit um einige Nanosekunden (was zu einer Erhöhung der Tests um 100 bis 200 ms führte). Ich kann nicht verstehen, warum das jemand tun würde, da es tatsächlich zusätzliche Arbeit ist, um die Leistung zu reduzieren.
Sie würden denken, das wäre optimiert ... obwohl ich vielleicht den Bytecode überprüfen und sehen sollte, was der Compiler tut. Das erklärt nicht, warum es für mich immer länger war, wenn es irgendwie optimiert ist ... deshalb frage ich mich, was los ist. Als Hinweis: Mit länger meine ich, den Test für 10000000 Iterationen auszuführen und dieses Programm mehrmals (10x +) auszuführen, hat immer gezeigt, dass es langsamer ist.
BEARBEITEN: Ein Test für Character.isDigit () wurde aktualisiert.
quelle
Der reguläre Ausdruck von CraigTP (siehe oben) führt zu einigen falsch positiven Ergebnissen. ZB "23y4" wird als Zahl gezählt, weil '.' Entspricht einem beliebigen Zeichen, das nicht dem Dezimalpunkt entspricht.
Außerdem wird jede Zahl mit einem führenden '+' abgelehnt.
Eine Alternative, die diese beiden kleinen Probleme vermeidet, ist
quelle
true
für ein einzelnes Plus"+"
oder Minus"-"
undfalse
für"0."
"0."
ist gültig fürDouble.parseDouble()
und ist ein gültiges Literal gemäß JLS ( §3.10.2 )!matches("-?\\d+([.]\\d+)?")
Wir können versuchen, alle Zahlen aus der angegebenen Zeichenfolge durch ("") zu ersetzen, dh ein Leerzeichen. Wenn danach die Länge der Zeichenfolge Null ist, können wir sagen, dass die angegebene Zeichenfolge nur Zahlen enthält. [Wenn Sie diese Antwort hilfreich fanden, ziehen Sie bitte eine Abstimmung in Betracht] Beispiel:
quelle
""
ist eine Nummer aber"3.14"
und"-1"
nicht?Sie können verwenden
NumberFormat#parse
:quelle
value
.Wenn Sie Java verwenden, um eine Android-App zu entwickeln, können Sie die Funktion TextUtils.isDigitsOnly verwenden.
quelle
Hier war meine Antwort auf das Problem.
Eine Catch-All-Convenience-Methode, mit der Sie einen beliebigen String mit einem beliebigen Parsertyp analysieren können :
isParsable(Object parser, String str)
. Der Parser kann einClass
oder ein seinobject
. Auf diese Weise können Sie auch benutzerdefinierte Parser verwenden, die Sie geschrieben haben und die für jedes Szenario funktionieren sollten, z.Hier ist mein Code mit Methodenbeschreibungen.
quelle
Verwenden Sie Folgendes, um nur positive Basis-Zehn-Ganzzahlen abzugleichen, die nur ASCII-Ziffern enthalten:
quelle
Ein leistungsfähiger Ansatz, der das Fangen von Versuchen vermeidet und mit negativen Zahlen und wissenschaftlicher Notation umgeht.
quelle
Hier ist meine Klasse, um zu überprüfen, ob eine Zeichenfolge numerisch ist. Es werden auch numerische Zeichenfolgen korrigiert:
Eigenschaften:
Bitte schön...
quelle
Hier ist ein weiteres Beispiel für ein aktualisiertes "CraigTP" -Regex-Matching mit mehr Validierungen.
quelle
Ausnahmen sind teuer, aber in diesem Fall dauert der RegEx viel länger. Der folgende Code zeigt einen einfachen Test von zwei Funktionen - eine mit Ausnahmen und eine mit Regex. Auf meinem Computer ist die RegEx-Version zehnmal langsamer als die Ausnahme.
quelle
// Bitte überprüfen Sie den folgenden Code
quelle
quelle
Dies ist ein einfaches Beispiel für diese Prüfung:
quelle
Sie können das Objekt java.util.Scanner verwenden.
quelle
Ich habe die Lösung von CraigTP so geändert, dass auch die wissenschaftliche Notation sowie Punkt und Komma als Dezimaltrennzeichen akzeptiert werden
Beispiel
quelle
Deshalb mag ich den Try * -Ansatz in .NET. Zusätzlich zu der traditionellen Parse-Methode, die der Java-Methode ähnelt, gibt es auch eine TryParse-Methode. Ich bin nicht gut in der Java-Syntax (out-Parameter?), Behandeln Sie daher Folgendes als eine Art Pseudocode. Es sollte das Konzept jedoch klar machen.
Verwendungszweck:
quelle
Analysieren Sie es (dh mit
Integer#parseInt
) und fangen Sie einfach die Ausnahme ab. =)Zur Verdeutlichung: Die Funktion parseInt prüft, ob sie die Nummer auf jeden Fall (offensichtlich) analysieren kann, und wenn Sie sie trotzdem analysieren möchten, werden Sie keinen Leistungseinbruch erleiden, wenn Sie die Analyse tatsächlich durchführen.
Wenn Sie es nicht analysieren möchten (oder sehr, sehr selten analysieren möchten), möchten Sie es natürlich natürlich anders machen.
quelle
Sie können NumberUtils.isCreatable () von Apache Commons Lang verwenden .
Da NumberUtils.isNumber in 4.0 veraltet ist, verwenden Sie stattdessen NumberUtils.isCreatable ().
quelle
Java 8 Stream, Lambda-Ausdruck, funktionale Schnittstelle
Alle behandelten Fälle ( Zeichenfolge null, Zeichenfolge leer usw. )
quelle
Ich habe einige Bedingungen dargestellt, um Zahlen und Dezimalstellen ohne Verwendung einer API zu überprüfen.
Überprüfen Sie die 1-stellige Nummer der Fixlänge
Überprüfen Sie die Nummer der festen Länge (Angenommen, die Länge beträgt 6).
Überprüfen Sie die Anzahl der unterschiedlichen Längen zwischen (Nehmen Sie eine Länge von 4 bis 6 an).
Überprüfen Sie die Dezimalzahl für die unterschiedliche Länge zwischen (Annahme einer Länge von 4 bis 7).
Hoffe, es wird vielen helfen.
quelle
Basierend auf anderen Antworten habe ich meine eigenen geschrieben und es werden keine Muster oder Parsing mit Ausnahmeprüfung verwendet.
Es wird auf maximal ein Minuszeichen und auf maximal einen Dezimalpunkt geprüft.
Hier einige Beispiele und deren Ergebnisse:
"1", "-1", "-1,5" und "-1,556" geben true zurück
"1..5", "1A.5", "1.5D", "-" und "--1" geben false zurück
Hinweis: Bei Bedarf können Sie dies ändern, um einen Locale-Parameter zu akzeptieren und diesen an die DecimalFormatSymbols.getInstance () -Aufrufe zu übergeben, um ein bestimmtes Gebietsschema anstelle des aktuellen zu verwenden.
quelle
Hier sind zwei Methoden, die funktionieren könnten. (Ohne Ausnahmen zu verwenden). Hinweis: Java ist standardmäßig ein Pass-by-Wert, und der Wert eines Strings ist die Adresse der Objektdaten des Strings. Also, wenn du es tust
Sie haben den Eingabewert so geändert, dass keine Leerzeichen mehr vorhanden sind. Sie können diese Zeile entfernen, wenn Sie möchten.
Hier ist eine andere Methode für den Fall, dass Sie Floats zulassen möchten. Diese Methode erlaubt angeblich, dass Zahlen in der Form 1.123.123.123.123.123.123 übergeben. Ich habe es gerade gemacht, und ich denke, es müssen weitere Tests durchgeführt werden, um sicherzustellen, dass es funktioniert.
quelle