Hoe te controleren of een tekenreeks numeriek is in Java

Hoe zou u controleren of een tekenreeks een getal was voordat u deze ontleden?


Antwoord 1, autoriteit 100%

Met Apache Commons Lang 3.5 en hoger: NumberUtils.isCreatable of StringUtils.isNumeric.

Met Apache Commons Lang 3.4 en lager: NumberUtils.isNumber of StringUtils.isNumeric.

Je kunt ook StringUtils.isNumericSpace die true retourneert voor lege tekenreeksen en interne spaties in de tekenreeks negeert. Een andere manier is om NumberUtils.isParsable die in feite controleert of het nummer parseerbaar is volgens Java. (De gekoppelde javadocs bevatten gedetailleerde voorbeelden voor elke methode.)


Antwoord 2, autoriteit 96%

Dit wordt over het algemeen gedaan met een eenvoudige, door de gebruiker gedefinieerde functie (d.w.z. Roll-your-own “isNumeric”-functie).

Zoiets als:

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

Als je deze functie echter veel aanroept, en je verwacht dat veel van de controles zullen mislukken omdat ze geen getal zijn, dan zal de prestatie van dit mechanisme niet geweldig zijn, omdat je vertrouwt op uitzonderingen die worden gegenereerd voor elke storing, wat een vrij dure operatie is.

Een alternatieve benadering kan zijn om een ​​reguliere expressie te gebruiken om te controleren of het een getal is:

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

Wees echter voorzichtig met het bovenstaande RegEx-mechanisme, aangezien het niet werkt als u niet-Arabische cijfers gebruikt (d.w.z. andere cijfers dan 0 tot en met 9). Dit komt omdat het “\d”-gedeelte van de RegEx alleen overeenkomt met [0-9] en in feite niet internationaal numeriek bekend is. (Met dank aan OregonGhost om hierop te wijzen!)

Of zelfs een ander alternatief is om Java’s ingebouwde java.text.NumberFormat object te gebruiken om te zien of, na het ontleden van de string, de parserpositie aan het einde van de string is. Als dat zo is, kunnen we aannemen dat de hele reeks numeriek is:

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

Antwoord 3, autoriteit 22%

als u Android gebruikt, moet u het volgende gebruiken:

android.text.TextUtils.isDigitsOnly(CharSequence str)

documentatie is hier te vinden

houd het simpel. meestal kan iedereen “herprogrammeren” (hetzelfde).


Antwoord 4, autoriteit 21%

Java 8 lambda-expressies.

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

Antwoord 5, autoriteit 17%

Zoals @CraigTP in zijn uitstekende antwoord had vermeld, heb ik ook vergelijkbare prestatieproblemen bij het gebruik van Exceptions om te testen of de string numeriek is of niet. Dus uiteindelijk splits ik de string en gebruik ik java.lang.Character.isDigit().

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

Volgens de Javadoc, Character.isDigit(char) herkent niet-Latijnse cijfers correct. Wat de prestaties betreft, denk ik dat een eenvoudig N-aantal vergelijkingen waarbij N het aantal tekens in de tekenreeks is, rekenkundig efficiënter zou zijn dan een regex-overeenkomst.

UPDATE: Zoals Jean-Francois Corbett in de opmerking aangaf, zou de bovenstaande code alleen positieve gehele getallen valideren, wat het grootste deel van mijn gebruiksscenario dekt. Hieronder vindt u de bijgewerkte code die decimale getallen correct valideert volgens de standaardlandinstelling die in uw systeem wordt gebruikt, met de veronderstelling dat het decimaalteken slechts één keer in de tekenreeks voorkomt.

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

Antwoord 6, autoriteit 6%

Google’s Guava-bibliotheek biedt een handige hulpmethode om dit te doen: Ints.tryParse. Je gebruikt het als Integer.parseInt maar het retourneert null in plaats van een Exception te genereren als de string niet naar een geldig geheel getal parseert. Merk op dat het Integer retourneert, niet int, dus je moet het terug converteren/autoboxen naar int.

Voorbeeld:

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

Vanaf de huidige release — Guava r11 — is deze echter nog steeds gemarkeerd met @Beta.

Ik heb het niet gebenchmarkt. Als we naar de broncode kijken, is er wat overhead van veel gezond verstandscontrole, maar uiteindelijk gebruiken ze Character.digit(string.charAt(idx)), vergelijkbaar, maar iets anders dan, het antwoord van @Ibrahim hierboven. Er is geen uitzondering voor het afhandelen van overhead onder de dekens bij de implementatie ervan.


Antwoord 7, autoriteit 4%

Gebruik Uitzonderingen niet om uw waarden te valideren.
Gebruik in plaats daarvan Util-bibliotheken zoals apache NumberUtils:

NumberUtils.isNumber(myStringValue);

Bewerken:

Houd er rekening mee dat, als uw tekenreeks met een 0 begint, NumberUtils uw waarde als hexadecimaal zal interpreteren.

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

Antwoord 8, autoriteit 3%

Waarom dringt iedereen aan op uitzonderings-/regex-oplossingen?

Hoewel ik kan begrijpen dat de meeste mensen het prima vinden om try/catch te gebruiken, kan het erg belastend zijn als je het vaak wilt doen.

Wat ik hier deed, was de regex, de parseNumber()-methoden en de array-zoekmethode gebruiken om te zien welke het meest efficiënt was. Deze keer keek ik alleen naar gehele getallen.

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

De resultaten in snelheid die ik kreeg 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: ik beweer niet dat deze methoden 100% zijn geoptimaliseerd, ze zijn alleen bedoeld om de gegevens te demonstreren

Uitzonderingen gewonnen als en alleen als het getal 4 tekens of minder is, en elke string is altijd een getal… in welk geval, waarom zelfs een cheque?

Kortom, het is buitengewoon pijnlijk als je vaak ongeldige nummers tegenkomt met de try/catch, wat logisch is. Een belangrijke regel die ik altijd volg is Gebruik NOOIT try/catch voor programmastroom. Dit is een voorbeeld waarom.

Interessant is dat de simpele if char <0 || >9 was uiterst eenvoudig te schrijven, gemakkelijk te onthouden (en zou in meerdere talen moeten werken) en wint bijna alle testscenario’s.

Het enige nadeel is dat ik vermoed dat Integer.parseInt() niet-ASCII-nummers kan verwerken, terwijl de array-zoekmethode dat niet doet.


Voor degenen die zich afvragen waarom ik zei dat het gemakkelijk is om de tekenreeks één te onthouden, als je weet dat er geen negatieve tekens zijn, kun je gemakkelijk wegkomen met iets beknopts als dit:

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;

Als laatste opmerking was ik benieuwd naar de toewijzingsoperator in het geaccepteerde voorbeeld met alle stemmen omhoog. Toevoegen in de toewijzing van

double d = Double.parseDouble(...)

is niet alleen nutteloos omdat je de waarde niet eens gebruikt, maar het verspilt ook verwerkingstijd en verhoogde de runtime met een paar nanoseconden (wat leidde tot een toename van 100-200 ms in de tests). Ik zie niet in waarom iemand dat zou doen, aangezien het eigenlijk extra werk is om de prestaties te verminderen.

Je zou denken dat dat geoptimaliseerd zou zijn… hoewel ik misschien de bytecode moet controleren en kijken wat de compiler doet. Dat verklaart niet waarom het altijd als langer voor mij verscheen, hoewel als het op de een of andere manier is geoptimaliseerd … daarom vraag ik me af wat er aan de hand is. Even een opmerking: met langer bedoel ik het uitvoeren van de test voor 10000000 iteraties, en als dat programma meerdere keren (10x+) werd uitgevoerd, bleek het altijd langzamer te zijn.

EDIT: een test voor Character.isDigit() bijgewerkt


Antwoord 9, autoriteit 3%

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

CraigTP’s reguliere expressie (hierboven weergegeven) produceert enkele valse positieven. bijv. “23y4” wordt geteld als een getal omdat ‘.’ komt overeen met elk teken dat niet de komma is.

Het zal ook elk nummer met een ‘+’ vooraan afwijzen

Een alternatief dat deze twee kleine problemen vermijdt, is

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

Antwoord 10, autoriteit 2%

We kunnen proberen alle getallen van de gegeven string te vervangen door (“”) dwz spatie en als daarna de lengte van de string nul is, dan kunnen we zeggen dat de gegeven string alleen getallen bevat.
Voorbeeld:

boolean isNumber(String str){
        if(str.length() == 0)
            return false; //To check if string is empty
        if(str.charAt(0) == '-')
            str = str.replaceFirst("-","");// for handling -ve numbers
        System.out.println(str);
        str = str.replaceFirst("\\.",""); //to check if it contains more than one decimal points
        if(str.length() == 0)
            return false; // to check if it is empty string after removing -ve sign and decimal point
        System.out.println(str);
        return str.replaceAll("[0-9]","").length() == 0;
    }

Antwoord 11, autoriteit 2%

U kunt NumberFormat#parse:

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

Antwoord 12

Als u java gebruikt om een ​​Android-app te ontwikkelen, kunt u TextUtils.isDigitsOnly functie.


Antwoord 13

Hier was mijn antwoord op het probleem.

Een handige methode die je kunt gebruiken om elke String met elk type parser te ontleden: isParsable(Object parser, String str). De parser kan een Class of een object zijn. Dit stelt je ook in staat om aangepaste parsers te gebruiken die je hebt geschreven en die voor altijd zouden moeten werken, bijvoorbeeld:

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 is mijn code, compleet met methodebeschrijvingen.

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

Antwoord 14

Een goed presterende aanpak waarbij try-catch wordt vermeden en het omgaan met negatieve getallen en wetenschappelijke notatie.

Pattern PATTERN = Pattern.compile( "^(-?0|-?[1-9]\\d*)(\\.\\d+)?(E\\d+)?$" );
public static boolean isNumeric( String value ) 
{
    return value != null && PATTERN.matcher( value ).matches();
}

Antwoord 15

Regex-overeenkomsten

Hier is nog een voorbeeld van een geüpgradede “CraigTP” regex-overeenkomst met meer validaties.

public static boolean isNumeric(String str)
{
    return str.matches("^(?:(?:\\-{1})?\\d+(?:\\.{1}\\d+)?)$");
}
  1. Slechts één minteken - toegestaan ​​en moet aan het begin staan.
  2. Na minteken moet er een cijfer staan.
  3. Slechts één decimaalteken . toegestaan.
  4. Na het decimaalteken moet een cijfer staan.

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

Antwoord 16

Als u alleen positieve gehele getallen met grondtal tien wilt matchen, die alleen ASCII-cijfers bevatten, gebruikt u:

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

Antwoord 17

Hier is mijn klasse om te controleren of een string numeriek is. Het corrigeert ook numerieke strings:

Kenmerken:

  1. Verwijdert onnodige nullen [“12000000” -> “12”]
  2. Verwijdert onnodige nullen [“12.0580000” -> “12.058”]
  3. Verwijdert niet-numerieke tekens [“12.00sdfsdf00” -> “12”]
  4. Verwerkt negatieve tekenreekswaarden [“-12.020000” -> “-12.02”]
  5. Verwijdert meerdere punten [“-12.0.20.000” -> “-12.02”]
  6. Geen extra bibliotheken, alleen standaard Java

Hier ga je…

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

Antwoord 18

Uitzonderingen zijn duur, maar in dit geval duurt de RegEx veel langer. De onderstaande code toont een eenvoudige test van twee functies: één met uitzonderingen en één met regex. Op mijn computer is de RegEx-versie 10 keer langzamer dan de uitzondering.

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

Antwoord 19

// controleer onderstaande 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;
}

Antwoord 20

U kunt het object java.util.Scanner gebruiken.

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

Antwoord 21

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

Antwoord 22

Dit is een eenvoudig voorbeeld voor deze controle:

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

Antwoord 23

Ik heb een aantal voorwaarden geïllustreerd om getallen en decimalen te controleren zonder een API te gebruiken,

Controleer Fixlengte 1-cijferig nummer

Character.isDigit(char)

Controleer het nummer van de fixlengte (neem aan dat de lengte 6) is

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

Controleer het variabele lengtenummer tussen (neem aan dat de lengte 4 tot 6 is)

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

Controleer decimaal getal van variabele lengte tussen (neem lengte van 4 tot 7 aan)

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

Ik hoop dat het velen zal helpen.


Antwoord 24

Gebaseerd op andere antwoorden die ik zelf heb geschreven en er worden geen patronen of parsering met uitzonderingscontrole gebruikt.

Het controleert op maximaal één minteken en controleert op maximaal één decimaalteken.

Hier zijn enkele voorbeelden en hun resultaten:

“1”, “-1”, “-1.5” en “-1.556” geven true terug

“1..5”, “1A.5”, “1.5D”, “-” en “–1” geven false terug

Opmerking: indien nodig kunt u dit wijzigen om een ​​Locale-parameter te accepteren en die door te geven aan de DecimalFormatSymbols.getInstance()-aanroepen om een ​​specifieke Locale te gebruiken in plaats van de huidige.

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

Antwoord 25

Ik heb CraigTP’s oplossing aangepast om wetenschappelijke notatie en zowel punten als komma’s als decimale scheidingstekens te accepteren

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

voorbeeld

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

Antwoord 26

Daarom hou ik van de Try*-benadering in .NET. Naast de traditionele Parse-methode die lijkt op de Java-methode, heb je ook een TryParse-methode. Ik ben niet goed in de Java-syntaxis (out-parameters?), dus behandel het volgende als een soort pseudo-code. Het moet het concept echter duidelijk maken.

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

Gebruik:

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

Antwoord 27

Ontdek het (dwz met Integer#parseInt ) en vang gewoon de uitzondering. =)

Ter verduidelijking: de parseInt-functie controleert of het het nummer in ieder geval (uiteraard) kan ontleden en als je het toch wilt ontleden, zul je geen prestatieverlies oplopen door het parseren daadwerkelijk uit te voeren.

Als je het niet zou willen ontleden (of het heel, heel zelden) zou je het natuurlijk anders willen doen.


Antwoord 28

U kunt NumberUtils.isCreatable() gebruiken van Apache Commons Lang.

Aangezien NumberUtils.isNumber in 4.0 wordt afgeschaft, moet u in plaats daarvan NumberUtils.isCreatable() gebruiken.


Antwoord 29

Java 8 Stream, lambda-expressie, functionele interface

Alle afgehandelde zaken (string null, string leeg 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();

Antwoord 30

Ik denk dat de enige manier om betrouwbaar te weten of een string een getal is, is om het te ontleden. Dus ik zou het gewoon ontleden, en als het een nummer is, krijg je het nummer gratis in een int!

LEAVE A REPLY

Please enter your comment!
Please enter your name here

Other episodes