it-swarm.com.de

So prüfen Sie, ob ein String in Java numerisch ist

Wie würden Sie prüfen, ob ein String vor dem Parsen eine Zahl war?

761
Craig Angus

Mit Apache Commons Lang 3.5 und höher: NumberUtils.isCreatable oder StringUtils.isNumeric .

Mit Apache Commons Lang 3.4 und darunter: NumberUtils.isNumber oder StringUtils.isNumeric .

Sie können auch StringUtils.isNumericSpace verwenden, der true für leere Zeichenfolgen zurückgibt und interne Leerzeichen in der Zeichenfolge ignoriert. Eine andere Möglichkeit ist die Verwendung von StringUtils.isParsable , das im Grunde prüft, ob die Nummer gemäß Java analysiert werden kann. (Die verknüpften Javadocs enthalten detaillierte Beispiele für jede Methode.)

618
palacsint

Dies geschieht im Allgemeinen mit einer einfachen benutzerdefinierten Funktion (d. H. Der eigenen Rolle "isNumeric").

So etwas wie:

public static boolean isNumeric(String str) { 
  try {  
    Double.parseDouble(str);  
    return true;
  } catch(NumberFormatException e){  
    return false;  
  }  
}

Wenn Sie jedoch diese Funktion häufig aufrufen und erwarten, dass viele der Überprüfungen fehlschlagen, weil keine Zahl vorhanden ist, ist die Leistung dieses Mechanismus nicht besonders gut, da Sie sich darauf verlassen, dass für jeden Fehler Ausnahmen ausgelöst werden. Das ist ein ziemlich teurer Vorgang.

Ein alternativer Ansatz kann darin bestehen, einen regulären Ausdruck zu verwenden, um die Gültigkeit einer Zahl zu prüfen:

public static boolean isNumeric(String str) {
  return str.matches("-?\\d+(\\.\\d+)?");  //match a number with optional '-' and decimal.
}

Seien Sie jedoch mit dem obigen RegEx-Mechanismus vorsichtig, da er fehlschlägt, wenn Sie nicht arabische Ziffern verwenden (d. H. 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. (Danke an OregonGhost für diesen Hinweis!)

Alternativ können Sie auch das integrierte Java.text.NumberFormat-Objekt von Java verwenden, um zu sehen, ob sich die Parserposition nach dem Parsen der Zeichenfolge am Ende der Zeichenfolge befindet. Wenn ja, können wir davon ausgehen, dass der gesamte String numerisch ist:

public static boolean isNumeric(String str) {
  NumberFormat formatter = NumberFormat.getInstance();
  ParsePosition pos = new ParsePosition(0);
  formatter.parse(str, pos);
  return str.length() == pos.getIndex();
}
828
CraigTP

wenn Sie Android verwenden, sollten Sie Folgendes verwenden:

Android.text.TextUtils.isDigitsOnly(CharSequence str)

Dokumentation finden Sie hier

halte es einfach. Meistens kann jeder "das gleiche" umprogrammieren.

138
Ahmed Alejo

Wie @CraigTP in seiner ausgezeichneten Antwort erwähnt hatte, habe ich auch ähnliche Bedenken hinsichtlich der Verwendung von Exceptions, um zu testen, ob die Zeichenfolge numerisch ist oder nicht. Am Ende teile ich den String auf und verwende Java.lang.Character.isDigit().

public static boolean isNumeric(String str)
{
    for (char c : str.toCharArray())
    {
        if (!Character.isDigit(c)) return false;
    }
    return true;
}

Gemäß der Javadoc erkennt Character.isDigit(char) nicht-lateinische Ziffern korrekt. In Bezug auf die Leistung denke ich, dass eine einfache Anzahl N von Vergleichen, bei denen N die Anzahl der Zeichen in der Zeichenfolge ist, rechnerisch effizienter ist als ein Regex-Abgleich.

UPDATE: Wie von Jean-François Corbett in dem Kommentar ausgeführt, würde der obige Code nur positive ganze Zahlen bestätigen, was die Mehrheit meines Anwendungsfalls abdeckt. Nachfolgend finden Sie den aktualisierten Code, der die Dezimalzahlen entsprechend dem in Ihrem System verwendeten Standardgebietsschema korrekt überprüft, wobei davon ausgegangen wird, dass das Dezimaltrennzeichen nur einmal in der Zeichenfolge auftritt.

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;
}
115
Ibrahim Arief

Java 8-Lambda-Ausdrücke.

String someString = "123123";
boolean isNumeric = someString.chars().allMatch( Character::isDigit );
80
Max Malysh

Die Guava-Bibliothek von Google bietet dazu eine Nice-Hilfsmethode: Ints.tryParse. Sie verwenden es wie Integer.parseInt, aber es gibt null zurück, anstatt eine Exception auszugeben, wenn die Zeichenfolge nicht in eine gültige Ganzzahl geparst wird. Beachten Sie, dass Integer zurückgegeben wird, nicht int. Daher müssen Sie es konvertieren/autobox zurück in int.

Beispiel:

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

Ab dem aktuellen Release - Guava r11 - ist es jedoch noch mit @Beta gekennzeichnet. 

Ich habe es nicht geprüft. Wenn man sich den Quellcode anschaut, gibt es einige Overheads durch eine Menge von Sanitätsprüfungen, aber am Ende verwenden sie Character.digit(string.charAt(idx)), ähnlich, aber etwas anders als die Antwort von @Ibrahim oben. Bei der Implementierung gibt es keinen zusätzlichen Overhead für die Behandlung von Ausnahmen.

42
quux00

Verwenden Sie keine Ausnahmen, um Ihre Werte zu überprüfen. Benutze Util libs stattdessen wie Apache NumberUtils:

NumberUtils.isNumber(myStringValue);

Bearbeiten :

Wenn Ihr String mit einer 0 beginnt, interpretiert NumberUtils Ihren Wert als Hexadezimal.

NumberUtils.isNumber("07") //true
NumberUtils.isNumber("08") //false
27
Goot

Warum drängt jeder auf AusnahmeRegex-Lösungen? - /

Ich kann zwar verstehen, dass die meisten Leute gut mit Try/Catch umgehen, wenn Sie es häufig machen wollen ... kann das extrem anstrengend sein.

Was ich hier gemacht habe, war die Regex, die parseNumber () - Methode und die Array-Suchmethode, um herauszufinden, welche Methode am effizientesten war. Dieses Mal habe ich nur ganzzahlige Zahlen betrachtet.

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;
}

Die Geschwindigkeitsergebnisse, die ich erhielt, 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 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

Disclaimer: Ich behaupte nicht, dass diese Methoden zu 100% optimiert sind, sie dienen nur der Demonstration der Daten.

Exceptions gewannen nur dann, wenn die Nummer 4 Zeichen oder weniger ist und jeder String immer eine Zahl ist ... in welchem ​​Fall, warum sogar einen Check? 

Kurz gesagt, es ist äußerst schmerzhaft, wenn Sie häufig mit dem Try/Catch auf ungültige Nummern stoßen, was Sinn macht. Eine wichtige Regel, die ich immer befolge, ist NIEMALS try/catch für den Programmablauf 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 ich davon ausgehe, dass Integer.parseInt () möglicherweise keine ASCII - Zahlen verarbeiten kann, die Array-Suchmethode jedoch nicht.


Für diejenigen, die sich wundern, warum ich gesagt habe, dass es leicht ist, sich an das Zeichen-Array zu erinnern. Wenn Sie wissen, dass es keine negativen Anzeichen gibt, können Sie leicht mit etwas Konkretem davonkommen:

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;

Zum Schluss war ich neugierig auf den Assigment-Operator im akzeptierten Beispiel mit allen Stimmen. Hinzufügen in der Zuordnung von

double d = Double.parseDouble(...)

ist nicht nur nutzlos, da Sie den Wert nicht einmal verwenden, sondern verschwendet Verarbeitungszeit und erhöht die Laufzeit um einige Nanosekunden (was zu einer Erhöhung der Tests um 100-200 ms führte). Ich kann nicht verstehen, warum jemand das tun würde, da es eigentlich zusätzliche Arbeit ist, die Leistung zu reduzieren.

Man könnte meinen, dass das optimiert werden würde ... vielleicht sollte ich den Bytecode überprüfen und sehen, was der Compiler macht. Das erklärt nicht, warum es für mich immer länger war, wenn es irgendwie optimiert wurde ... daher frage ich mich, was los ist. Als Anmerkung: Langfristig meine ich, den Test für 10000000 Iterationen auszuführen und das Programm mehrmals auszuführen (10x +), zeigte immer, dass es langsamer ist.

BEARBEITEN: Ein Test für Character.isDigit () wurde aktualisiert.

20
Water
public static boolean isNumeric(String str)
{
    return str.matches("-?\\d+(.\\d+)?");
}

Der reguläre Ausdruck von CraigTP (oben gezeigt) führt zu einigen Fehlalarmen. Z.B. "23y4" wird als Zahl gezählt, da "." passt zu jedem Zeichen, das nicht dem Dezimalpunkt entspricht.

Außerdem wird jede Nummer mit einem führenden "+" abgelehnt.

Eine Alternative, die diese beiden kleineren Probleme vermeidet, ist

public static boolean isNumeric(String str)
{
    return str.matches("[+-]?\\d*(\\.\\d+)?");
}
18
user872985

Sie können NumberFormat#parse verwenden:

try
{
     NumberFormat.getInstance().parse(value);
}
catch(ParseException e)
{
    // Not a number.
}
12
Artem Barger

Wenn Sie Java zur Entwicklung der Android-App verwenden, können Sie die Funktion TextUtils.isDigitsOnly verwenden.

11
Eric Guo

Wir können versuchen, alle Zahlen der angegebenen Zeichenfolge durch ("") zu ersetzen, dh 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 als hilfreich empfunden haben, überlegen Sie bitte, ob Sie sie bewerten] Beispiel: 

boolean isNumber(String str){
       return str.replaceAll("[0-9]","").length() == 0;
}
8
Ketan Ramteke

Hier war meine Antwort auf das Problem.

Eine bequeme Methode, mit der Sie jeden String mit einem beliebigen Parser-Typ analysieren können: isParsable(Object parser, String str). Der Parser kann eine Class oder eine object sein. Auf diese Weise können Sie auch benutzerdefinierte Parser verwenden, die Sie geschrieben haben und 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 
 */
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;
    }
}
8
Jamie Bell

Um nur positive ganze Zahlen der Basis 10 zu finden, die nur ASCII - Ziffern enthalten, verwenden Sie:

public static boolean isNumeric(String maybeNumeric) {
    return maybeNumeric != null && maybeNumeric.matches("[0-9]+");
}
5
user11153

Regex Matching

Hier ist ein weiteres Beispiel eines aktualisierten "CraigTP" -Regex-Abgleichs mit mehr Validierungen.

public static boolean isNumeric(String str)
{
    return str.matches("^(?:(?:\\-{1})?\\d+(?:\\.{1}\\d+)?)$");
}
  1. Nur ein negatives Vorzeichen - erlaubt und muss am anfang sein.
  2. Nach dem negativen Vorzeichen muss eine Ziffer stehen.
  3. Nur ein Dezimalzeichen . dürfen.
  4. Nach dem Dezimalzeichen muss eine Ziffer stehen.

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
5
Madan Sapkota

Ein leistungsfähiger Ansatz, der den Versuch verhindert, negative Zahlen und wissenschaftliche Notationen zu verarbeiten.

Pattern PATTERN = Pattern.compile( "^(-?0|-?[1-9]\\d*)(\\.\\d+)?(E\\d+)?$" );

public static boolean isNumeric( String value ) 
{
    return value != null && PATTERN.matcher( value ).matches();
}
5
lars

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 Computer 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);

}

}
5
ChrisCantrell

Hier ist meine Klasse zur Überprüfung, ob eine Zeichenfolge numerisch ist. Es korrigiert auch numerische Zeichenfolgen:

Eigenschaften:

  1. Entfernt unnötige Nullen ["12.0000000" -> "12"] 
  2. Entfernt unnötige Nullen ["12.0580000" -> "12.058"] 
  3. Entfernt nicht numerische Zeichen ["12.00sdfsdf00" -> "12"] 
  4. Verarbeitet negative Stringwerte ["-12,020000" -> "-12.02"]
  5. Entfernt mehrere Punkte ["-12.0.20.000" -> "-12.02"]
  6. Keine zusätzlichen Bibliotheken, nur Standard-Java

Bitte schön...

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;
    }

}
5
Meatball

// Bitte überprüfen Sie den Code

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;
}
4
Tejas Parmar

Dies ist ein einfaches Beispiel für diese Überprüfung:

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;
}
3
ARIJIT
// 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;
    }
}
3
Elye M.

Sie können das Java.util.Scanner-Objekt verwenden.

public static boolean isNumeric(String inputData) {
      Scanner sc = new Scanner(inputData);
      return sc.hasNextInt();
    }
3
Yu Wai Hlaing

Sie können NumberUtils.isCreatable () von Apache Commons Lang verwenden.

Da NumberUtils.isNumber in 4.0 nicht mehr empfohlen wird, verwenden Sie NumberUtils.isCreatable ().

2
Cenxui

Analysieren Sie es (d. H. Mit Integer#parseInt ) und fangen Sie einfach die Ausnahme ab. =)

Zur Klarstellung: Die parseInt-Funktion prüft, ob die Nummer in jedem Fall (offensichtlich) analysiert werden kann. Wenn Sie sie dennoch analysieren möchten, werden Sie durch das Parsen der Performance keinen Performance-Treffer erzielen.

Wenn Sie es nicht analysieren möchten (oder sehr, sehr selten), möchten Sie es natürlich anders machen.

2
gha.st

Deshalb mag ich den Try * -Ansatz in .NET. Neben 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?). Es sollte das Konzept jedoch klarstellen.

boolean parseInteger(String s, out int number)
{
    try {
        number = Integer.parseInt(myString);
        return true;
    } catch(NumberFormatException e) {
        return false;
    }
}

Verwendungszweck:

int num;
if (parseInteger("23", out num)) {
    // Do something with num.
}
2
OregonGhost

Ich habe die CraigTP-Lösung dahingehend geändert, dass wissenschaftliche Notation und Punkt und Komma als Dezimaltrennzeichen akzeptiert werden

^-?\d+([,\.]\d+)?([eE]-?\d+)?$

beispiel

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
2
AndyTheEntity

Java 8 Stream, Lambda-Ausdruck, funktionale Schnittstelle

Alle behandelten Fälle ( String null, String leer etc

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();
1
Noor Nawaz

Sie könnten BigDecimal verwenden, wenn der String Dezimalzahlen enthalten kann:

try {
    new Java.math.BigInteger(testString);
} catch(NumberFormatException e) {
    throw new RuntimeException("Not a valid number");
}
1
Dayanand

Dies ist der schnellste Weg, den ich kennen kann, um zu überprüfen, ob String die Nummer ist oder nicht:

public static boolean isNumber(String str){
  int i=0, len=str.length();
  boolean a=false,b=false,c=false, d=false;
  if(i<len && (str.charAt(i)=='+' || str.charAt(i)=='-')) i++;
  while( i<len && isDigit(str.charAt(i)) ){ i++; a=true; }
  if(i<len && (str.charAt(i)=='.')) i++;
  while( i<len && isDigit(str.charAt(i)) ){ i++; b=true; }
  if(i<len && (str.charAt(i)=='e' || str.charAt(i)=='E') && (a || b)){ i++; c=true; }
  if(i<len && (str.charAt(i)=='+' || str.charAt(i)=='-') && c) i++;
  while( i<len && isDigit(str.charAt(i)) ){ i++; d=true;}
  return i==len && (a||b) && (!c || (c && d));
}
static boolean isDigit(char c){
  return c=='0' || c=='1' || c=='2' || c=='3' || c=='4' || c=='5' || c=='6' || c=='7' || c=='8' || c=='9';
}
1
user3870075

Parallele Überprüfung auf sehr lange Zeichenfolgen mit IntStream

In Java 8 wird mit den folgenden Tests geprüft, ob alle Zeichen der angegebenen string zwischen '0' und '9' liegen. Beachten Sie, dass die leere Zeichenfolge akzeptiert wird:

string.chars().unordered().parallel().allMatch( i -> '0' <= i && '9' >= i )

Basierend auf anderen Antworten habe ich meine eigenen geschrieben und es werden keine Muster oder Parsen mit Ausnahmeprüfung verwendet.

Es prüft auf maximal ein Minuszeichen und auf maximal eine Dezimalstelle.

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 übergeben, um eine bestimmte Locale anstelle der aktuellen zu verwenden.

 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;
}
1
Josh Gager

Ich habe einige Bedingungen erläutert, um Zahlen und Dezimalzahlen ohne API zu überprüfen.

Überprüfen Sie die 1-stellige Fixlänge

Character.isDigit(char)

Nummer der Fixlänge überprüfen (Angenommen, Länge ist 6)

String number = "132452";
if(number.matches("([0-9]{6})"))
System.out.println("6 digits number identified");

Überprüfen Sie die Anzahl der variierenden Längen zwischen (angenommene Länge 4 bis 6)

//  {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");

Überprüfen Sie die Dezimalzahl der variierenden Länge zwischen (angenommene Länge 4 bis 7).

//  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");

Hoffe, es wird vielen helfen.

1
ArifMustafa

Wenn ihr die folgende Methode benutzt, um zu überprüfen:

public static boolean isNumeric(String str) {
    NumberFormat formatter = NumberFormat.getInstance();
    ParsePosition pos = new ParsePosition(0);
    formatter.parse(str, pos);
    return str.length() == pos.getIndex();
}

Was ist dann mit der Eingabe eines sehr langen Strings passiert, wie ich diese Methode nenne:

System.out.println(isNumeric("94328948243242352525243242524243425452342343948923"));

Das Ergebnis ist "true", es ist auch eine zu große Zahl! Das Gleiche passiert, wenn Sie regex zum Überprüfen verwenden. so was:

public static boolean isNumeric(String str) {
    try {
        int number = Integer.parseInt(str);
        return true;
    } catch (Exception e) {
        return false;
    }
}

Und das Ergebnis ist was ich erwartet habe!

1
Tạ Anh Tú

Hier sind zwei Methoden, die funktionieren könnten. (Ohne Ausnahmen zu verwenden) . Hinweis: Java ist standardmäßig ein Wert-für-Wert und der Wert eines Strings ist die Adresse der Objektdaten des Strings . Wenn Sie dies tun 

stringNumber = stringNumber.replaceAll(" ", "");

Sie haben den Eingabewert so geändert, dass er keine Leerzeichen enthält. Sie können diese Zeile entfernen, wenn Sie möchten.

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;
}

Hier ist eine andere Methode für den Fall, dass Sie Floats zulassen möchten. Diese Methode lässt angeblich zu, dass Zahlen im Formular übergeben werden. 1,123,123,123,123,123,123 Ich habe es gerade erst erstellt, und ich denke, es muss noch getestet werden, um sicherzustellen, dass es funktioniert.

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;
}
1
XForCE07

Ich denke, der einzige Weg, um zuverlässig zu erkennen, ob eine Zeichenfolge eine Zahl ist, besteht darin, sie zu analysieren. Also würde ich es einfach analysieren, und wenn es sich um eine Nummer handelt, erhalten Sie die Nummer in einem int kostenlos!

0
jqno

Versuche dies:

public  boolean isNumber(String str)
{       
    short count = 0;
    char chc[]  = {'0','1','2','3','4','5','6','7','8','9','.','-','+'};
    for (char c : str.toCharArray())
    {   
        for (int i = 0;i < chc.length;i++)
        {
            if( c  == chc[i]){
                count++;        
            }
         }                      
    }
    if (count != str.length() ) 
        return false;
    else
        return true;
}
0
Hans van Kraaij

Wenn Sie die Überprüfung mit einem regulären Ausdruck durchführen möchten, müssen Sie ein endgültiges statisches Musterobjekt erstellen. Auf diese Weise muss der reguläre Ausdruck nur einmal kompiliert werden. Das Kompilieren des regulären Ausdrucks dauert ungefähr so ​​lange, wie das Match ausgeführt wird. Durch diese Vorsichtsmaßnahme verkürzen Sie die Ausführungszeit der Methode um die Hälfte.

final static Pattern NUMBER_PATTERN = Pattern.compile("[+-]?\\d*\\.?\\d+");

static boolean isNumber(String input) {
    Matcher m = NUMBER_PATTERN.matcher(input);
    return m.matches();
}

Ich gehe davon aus, dass eine Zahl eine Zeichenfolge ist, die nur Dezimalstellen enthält, möglicherweise ein + oder - Zeichen am Anfang und höchstens einen Dezimalpunkt (nicht am Ende) und keine anderen Zeichen (einschließlich Kommas, Leerzeichen, Zahlen in andere Zählsysteme, römische Ziffern, Hieroglyphen).

Diese Lösung ist prägnant und ziemlich schnell, aber Sie können ein paar Millisekunden pro Million Aufrufe abrufen, wenn Sie so vorgehen

static boolean isNumber(String s) {
    final int len = s.length();
    if (len == 0) {
        return false;
    }
    int dotCount = 0;
    for (int i = 0; i < len; i++) {
        char c = s.charAt(i);
        if (c < '0' || c > '9') {
            if (i == len - 1) {//last character must be digit
                return false;
            } else if (c == '.') {
                if (++dotCount > 1) {
                    return false;
                }
            } else if (i != 0 || c != '+' && c != '-') {//+ or - allowed at start
                return false;
            }

        }
    }
    return true;
}
0
mikeyreilly