Wie würden Sie prüfen, ob ein String eine Zahl ist, bevor Sie ihn parsen?
In der Frage steht "numerisch", was auch nicht-ganzzahlige Werte einschließen könnte.
Wie würden Sie prüfen, ob ein String eine Zahl ist, bevor Sie ihn parsen?
Regex-Abgleich
Hier ist ein weiteres Beispiel, das den "CraigTP"-Regex-Abgleich mit weiteren Validierungen erweitert.
public static boolean isNumeric(String str)
{
return str.matches("^(?:(?:\\-{1})?\\d+(?:\\.{1}\\d+)?)$");
}
Regex-Test
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
Hier ist meine Klasse zur Überprüfung, ob eine Zeichenkette numerisch ist. Sie korrigiert auch numerische Zeichenketten:
Hier, bitte sehr...
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;
}
}
Ausnahmen sind teuer, aber in diesem Fall dauert das RegEx viel länger. Der folgende Code zeigt einen einfachen Test von zwei Funktionen - eine mit Ausnahmen und eine mit Regex. Auf meinem Rechner ist die RegEx-Version 10 Mal langsamer als die Ausnahme.
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);
}
}
Im Allgemeinen denke ich, dass diese Art von Code verwendet werden würde, um Dinge wie getippte Eingaben zu überprüfen. In diesem Fall spielt die Geschwindigkeit keine Rolle, und etwas so Hässliches wie das Auslösen einer Ausnahme, um zu prüfen, ob es sich um eine Zahl oder eine Nicht-Zahl handelt, ist falsch.
Vielleicht auch nicht. Getippte Eingaben werden in der Regel von der UI-Komponente geprüft, wobei Fehler sofort angezeigt werden können, bevor der Wert übermittelt wird. Üblicher ist es, Strings aus großen Textdateien zu validieren, bei denen die Leistung eine Rolle spielt. Das Ziel meiner Antwort hier ist es, die Aussage "Ausnahmen sind langsam" in der akzeptierten Antwort anzusprechen. Komplexe Regex ist viel teurer. Und es gibt überhaupt keinen "hässlichen Wurf" in meinem Code - nur einen schnelleren Weg, um Verletzungen zu erkennen. Bei einem Ansatz, bei dem man zuerst prüft und dann berechnet, macht man zwei Durchgänge durch die Eingabe: einen zum Prüfen und dann einen weiteren zum Konvertieren.
"Auf meinem Rechner ist die RegEx-Version 10 Mal langsamer als die Ausnahmeversion." - Das liegt nur daran, dass Sie einen Wert testen, der numerisch ist, so dass die Ausnahme nie ausgelöst wird. Testen Sie dies auf nicht numerischen Wert, und die Version mit Ausnahme wird langsamer sein als Regex ein.
Ich habe einige Bedingungen zur Überprüfung von Zahlen und Dezimalstellen ohne Verwendung einer API dargestellt,
Check Fix Länge 1-stellige Zahl
Character.isDigit(char)
Prüfen Sie die Nummer der festen Länge (angenommen, die Länge ist 6)
String number = "132452";
if(number.matches("([0-9]{6})"))
System.out.println("6 digits number identified");
Prüfen Sie die Anzahl der variablen Längen zwischen (nehmen Sie 4 bis 6 Längen an)
// {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");
Variierende Länge Dezimalzahl zwischen (4 bis 7 Länge vorausgesetzt)
// 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");
Ich hoffe, es wird vielen helfen.
CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.
42 Stimmen
Alle Lösungen, die mit regulären Ausdrücken vorgeschlagen werden, funktionieren nicht für hexadezimale Zahlen.
0 Stimmen
Und die Übergabe einer Null-Zeichenkette in der Funktion matches(...) führt zur Ausnahme NullPointer.
0 Stimmen
In der Antwort von Max Malysh finden Sie eine prägnante Java 8-Lösung ohne Bibliotheken von Drittanbietern.
0 Stimmen
@HiteshSahu Null-Strings scheinen in der neuesten Version (einschließlich Java 6.x und 7.x) ordnungsgemäß behandelt zu werden.
0 Stimmen
Alle vorgeschlagenen Lösungen zur Verwendung
Integer.parseInt()
nicht in der Lage, Handynummern zu analysieren, dieNumberFormatException
.0 Stimmen
@OscarCastiblanco Alle Zeichenketten sind Zahlen in einer bestimmten Basis.