Java String Vedere se una stringa contiene solo numeri e non lettere

Ho una stringa che ho caricato tutta la mia applicazione, e cambia da numeri a lettere e tale. Ho un semplice if istruzione per vedere se contiene lettere o numeri, ma qualcosa non funziona correttamente. Ecco un frammento.

String text = "abc"; 
String number; 

if (text.contains("[a-zA-Z]+") == false && text.length() > 2) {
    number = text; 
}

Anche se il text variabile contiene lettere, la condizione restituisce come true. E && dovrebbe eval sia come condizioni di dover essere true al fine di elaborare il number = text;

==============================

Soluzione:

Sono stato in grado di risolvere questo problema utilizzando il seguente codice fornito da un commento su questa questione. Tutti gli altri post sono validi, come pure!

Quello che ho usato, che ha lavorato venuto dal primo commento. Anche se tutti i codici di esempio fornito sembra essere valido, come pure!

String text = "abc"; 
String number; 

if (Pattern.matches("[a-zA-Z]+", text) == false && text.length() > 2) {
    number = text; 
}
  • contiene non prendere una regexp come input. Utilizzare matches("\\d{2,}") o provare con un Pattern e Matcher
  • Può la stringa in un valore decimale o solo i valori interi?
  • Perché sei in controllo del testo.length() > 2? Qual è la ragione?
  • Pattern.matches("[a-zA-Z]+", text) == false può essere semplificata per !Pattern.matches("[a-zA-Z]+", text)
  • Utilizzo di java API boolean isNumeric = someString.chars().allMatch(x -> Character.isDigit(x)); forma Max Malysh Post.
InformationsquelleAutor RedHatcc | 2012-05-13



16 Replies
  1. 312

    Se sarete trattamento il numero come testo, quindi modifica:

    if (text.contains("[a-zA-Z]+") == false && text.length() > 2){

    a:

    if (text.matches("[0-9]+") && text.length() > 2) {

    Invece di controllare che la stringa non contenere caratteri alfabetici, controllare per essere sicuri che esso contiene solo numerici.

    Se si desidera effettivamente utilizzare il valore numerico, utilizzo Integer.parseInt() o Double.parseDouble() come altri hanno spiegato di seguito.


    Come nota a margine, è generalmente considerato cattiva pratica per confrontare i valori booleani per true o false. Basta usare if (condition) o if (!condition).

    • Probabilmente si desidera aggiungere tasselli (es. ^[0-9]+$) altrimenti abc123def sarà considerato un numero.
    • Io non credo che sia necessario. matches() restituisce true se e solo se è una partita completa, dall’inizio alla fine.
    • “^-?\d+\.?\d*$” confronta la stringa intera e solo se è un numero valido (negativi e decimali compresi). Per esempio, non sarà partita 1, 10, 1.0, -1, -1.0, ecc. Inoltre il match sul “1.” ma che, spesso, può essere analizzato in ogni caso.
    • Non c’è bisogno di chiamare && (text.length() > 2). Tutto può essere controllato espressione regolare: if (text.matches("[0-9]{3,}")
  2. 20

    È inoltre possibile utilizzare NumberUtil.isCreatable(String str) da Apache Commons

    • Non credo NumberUtil.isCreatable(String str) è corretto utilizzare per quello che la domanda chiede. E. g., NumberUtil.isCreatable( "09" ) restituisce false, anche se "09" contiene solo numeri.
  3. 12

    Questo è come vorrei fare:

    if(text.matches("^[0-9]*$") && text.length() > 2){
        //...
    }

    Il $ evitare una corrispondenza parziale e.g; 1B.

    • Non ho bisogno di text.length() > 2 parte, così l’ho sostituito ^[0-9]*$ da ^[0-9]+$ per essere sicuro di avere almeno un numero.
  4. 7

    Prestazioni-saggio parseInt e tali sono molto worser rispetto ad altre soluzioni, perché almeno richiedono la gestione delle eccezioni.

    Ho eseguito jmh prove e hanno trovato che l’iterazione su Stringa utilizzando charAt e il confronto di caratteri con limite di caratteri è il modo più veloce per verificare se la stringa contiene solo cifre.

    JMH test

    Prove a confronto le prestazioni di Character.isDigit vs Pattern.matcher().matches vs Long.parseLong vs controllo valori char.

    Questi modi può produrre risultati diversi per i non-ascii stringhe e le stringhe che contengono +/- segni.

    Test di Throughput modalità (maggiore è meglio) con 5 riscaldamento iterazioni e 5 ripetizioni di test.

    Risultati

    Nota che parseLong è quasi 100 volte più lento rispetto a isDigit per il primo test di carico.

    ## Test load with 25% valid strings (75% strings contain non-digit symbols)
    
    Benchmark       Mode  Cnt  Score   Error  Units
    testIsDigit    thrpt    5  9.275 ± 2.348  ops/s
    testPattern    thrpt    5  2.135 ± 0.697  ops/s
    testParseLong  thrpt    5  0.166 ± 0.021  ops/s
    
    ## Test load with 50% valid strings (50% strings contain non-digit symbols)
    
    Benchmark              Mode  Cnt  Score   Error  Units
    testCharBetween       thrpt    5  16.773 ± 0.401  ops/s
    testCharAtIsDigit     thrpt    5  8.917 ± 0.767  ops/s
    testCharArrayIsDigit  thrpt    5  6.553 ± 0.425  ops/s
    testPattern           thrpt    5  1.287 ± 0.057  ops/s
    testIntStreamCodes    thrpt    5  0.966 ± 0.051  ops/s
    testParseLong         thrpt    5  0.174 ± 0.013  ops/s
    testParseInt          thrpt    5  0.078 ± 0.001  ops/s

    Suite di Test

    @State(Scope.Benchmark)
    public class StringIsNumberBenchmark {
        private static final long CYCLES = 1_000_000L;
        private static final String[] STRINGS = {"12345678901","98765432177","58745896328","35741596328", "123456789a1", "1a345678901", "1234567890 "};
        private static final Pattern PATTERN = Pattern.compile("\\d+");
    
        @Benchmark
        public void testPattern() {
            for (int i = 0; i < CYCLES; i++) {
                for (String s : STRINGS) {
                    boolean b = false;
                    b = PATTERN.matcher(s).matches();
                }
            }
        }
    
        @Benchmark
        public void testParseLong() {
            for (int i = 0; i < CYCLES; i++) {
                for (String s : STRINGS) {
                    boolean b = false;
                    try {
                        Long.parseLong(s);
                        b = true;
                    } catch (NumberFormatException e) {
                        //no-op
                    }
                }
            }
        }
    
        @Benchmark
        public void testCharArrayIsDigit() {
            for (int i = 0; i < CYCLES; i++) {
                for (String s : STRINGS) {
                    boolean b = false;
                    for (char c : s.toCharArray()) {
                        b = Character.isDigit(c);
                        if (!b) {
                            break;
                        }
                    }
                }
            }
        }
    
        @Benchmark
        public void testCharAtIsDigit() {
            for (int i = 0; i < CYCLES; i++) {
                for (String s : STRINGS) {
                    boolean b = false;
                    for (int j = 0; j < s.length(); j++) {
                        b = Character.isDigit(s.charAt(j));
                        if (!b) {
                            break;
                        }
                    }
                }
            }
        }
    
        @Benchmark
        public void testIntStreamCodes() {
            for (int i = 0; i < CYCLES; i++) {
                for (String s : STRINGS) {
                    boolean b = false;
                    b = s.chars().allMatch(c -> c > 47 && c < 58);
                }
            }
        }
    
        @Benchmark
        public void testCharBetween() {
            for (int i = 0; i < CYCLES; i++) {
                for (String s : STRINGS) {
                    boolean b = false;
                    for (int j = 0; j < s.length(); j++) {
                        char charr = s.charAt(j);
                        b = '0' <= charr && charr <= '9';
                        if (!b) {
                            break;
                        }
                    }
                }
            }
        }
    }

    Aggiornamento del 23-Feb-2018

    • Aggiungere altri due casi, uno usando charAt invece di creare servizi extra e un altro utilizzando IntStream di char codici
    • Aggiungere immediata se non cifre trovati per loop casi di test
    • Return false per stringa vuota per loop casi di test

    Aggiornamento del 23-Feb-2018

    • Aggiungere uno o più casi di test (il più veloce!) che mette a confronto il valore char senza l’utilizzo di stream
    • Se guardi il codice di toCharArray, è l’allocazione di un array di char e copia i caratteri (penso che potrebbe essere costoso). Che dire, se basta scorrere la stringa utilizzando un indice e charAt, sarebbe più veloce? Sarebbe interessante anche se si potrebbe aggiungere la soluzione di Andy per il test: boolean isNum = testo.caratteri().allMatch(c -> c >= 48 && c <= 57)
  5. 2

    Apache Commons Lang fornisce org.apache.commons.lang.StringUtils.isNumeric(CharSequence cs), che prende come argomento un String e controlla se esso consiste puramente di caratteri numerici (compresi i numeri non latino script). Tale metodo restituisce false se ci sono personaggi come spazio, meno, più, e i separatori decimali, ad esempio una virgola e punto.

    Altri metodi della classe consentire ulteriori controlli numerici.

    • Questo dovrebbe essere molto più veloce di una regex; ecco l’attuazione: public static boolean isNumeric(String str) { if (str == null) { return false; } else { int sz = str.length(); for(int i = 0; i < sz; ++i) { if (!Character.isDigit(str.charAt(i))) { return false; } } return true; } }
  6. 1

    Ci sono un sacco di servizi per ottenere i numeri da Strings in Java (e viceversa). Si potrebbe desiderare di saltare la regex parte di ricambio te la complicazione di che.

    Per esempio, si potrebbe provare e vedere che cosa Doppio.parseDouble(String s) restituisce per voi. Dovrebbe lanciare un NumberFormatException se non trova un appropriato valore di stringa. Vorrei suggerire questa tecnica, perché si potrebbe effettivamente fare uso di il valore rappresentato dal String come un tipo numerico.

    • Utilizzando un’eccezione perché al test di ingresso potrebbe essere una cattiva idea, eccezioni a creare una grande testa.
    • Sono d’accordo che le eccezioni non sono un ottimo modo per gestire previsto per i casi che stanno per sorgere. Comunque penso sia difficile dire se ci sarebbe un calo di prestazioni, senza più contesto.
  7. 1

    È possibile utilizzare Regex.Partita

    if(text.matches("\\d*")&& text.length() > 2){
        System.out.println("number");
    }

    O si potrebbe utilizzare onversions come Integer.parseInt(String) o meglio Long.parseLong(String) per numeri più grandi
    come ad esempio:

    private boolean onlyContainsNumbers(String text) {
        try {
            Long.parseLong(text);
            return true;
        } catch (NumberFormatException ex) {
            return false;
        }
    } 

    E poi prova con:

    if (onlyContainsNumbers(text) && text.length() > 2) {
        //do Stuff
    }
    • .partite(“^\\d+$”)
  8. 1

    Sotto regexs può essere utilizzato per controllare se una stringa è solo un numero o non:

    if (str.matches(".*[^0-9].*")) or if (str.matches(".*\\D.*"))

    Entrambe le condizioni di cui sopra sarà di ritorno true se la Stringa contiene non di numeri. Su false, stringa ha solo i numeri.

  9. 1

    Al fine di controllare semplicemente la stringa che contiene solo LETTERE, utilizzare il codice riportato di seguito :

    if (text.matches("[a-zA-Z]+"){
       //your operations
    }

    Al fine di controllare semplicemente la stringa che contiene solo un NUMERO di codice riportato di seguito :

    if (text.matches("[0-9]+"){
       //your operations
    }

    Spero che questo vi aiuterà a qualcuno!

  10. 0

    Questo codice è già scritto. Se non ti dispiace (molto) minore calo di prestazioni-che probabilmente non è di peggio che fare una regex match, utilizzare Integer.parseInt() o Doppio.parseDouble(). Che ti dirò subito se una Stringa è solo numeri (o è un numero, come appropriato). Se avete bisogno di gestire più stringhe di numeri, BigInteger e BigDecimal sport costruttori che accettano le Stringhe. Uno di questi sarà lanciare un NumberFormatException se si tenta di passare un non-numero (integrale o decimale, in base a quella che si sceglie, ovviamente). In alternativa, a seconda delle tue esigenze, basta scorrere i caratteri nella Stringa e controllare Carattere.isDigit() e/o Carattere.isLetter().

  11. 0
    import java.util.*;
    
    class Class1 {
        public static void main(String[] argh) {
            boolean ans = CheckNumbers("123");
            if (ans == true) {
                System.out.println("String contains numbers only");
            } else {
                System.out.println("String contains other values as well");
    
            }
        }
    
    
        public static boolean CheckNumbers(String input) {
            for (int ctr = 0; ctr < input.length(); ctr++) {
                if ("1234567890".contains(Character.valueOf(input.charAt(ctr)).toString())) {
                    continue;
                } else {
                    return false;
                }
            }
            return true;
        }
    }
  12. 0
    Character first_letter_or_number = query.charAt(0);
                    //------------------------------------------------------------------------------
                    if (Character.isDigit())
                    {
    
                    }
                    else if (Character.isLetter())
                    {
    
                    }
  13. 0

    Di lavoro test di esempio

    import java.util.regex.Matcher;
    import java.util.regex.Pattern;
    
    import org.apache.commons.lang3.StringUtils;
    
    public class PaserNo {
    
        public static void main(String args[]) {
    
            String text = "gg";
    
            if (!StringUtils.isBlank(text)) {
                if (stringContainsNumber(text)) {
                    int no=Integer.parseInt(text.trim());
                    System.out.println("inside"+no);
    
                } else {
                    System.out.println("Outside");
                }
            }
            System.out.println("Done");
        }
    
        public static boolean stringContainsNumber(String s) {
            Pattern p = Pattern.compile("[0-9]");
            Matcher m = p.matcher(s);
            return m.find();
        }
    }

    Ancora il tuo codice può essere rottura con i “1a”, ecc quindi, è necessario controllare eccezione

    if (!StringUtils.isBlank(studentNbr)) {
                    try{
                        if (isStringContainsNumber(studentNbr)){
                        _account.setStudentNbr(Integer.parseInt(studentNbr.trim()));
                    }
                    }catch(Exception e){
                        e.printStackTrace();
                        logger.info("Exception during parse studentNbr"+e.getMessage());
                    }
                }

    Metodo per il controllo non è di stringa o di non

    private boolean isStringContainsNumber(String s) {
            Pattern p = Pattern.compile("[0-9]");
            Matcher m = p.matcher(s);
            return m.find();
        }
  14. 0

    È una cattiva pratica di coinvolgere eccezione di lancio/gestione in un tale scenario tipico.

    Quindi un parseInt() non è bello, ma un’espressione regolare è una soluzione elegante per questo, ma prendere cura dei seguenti:

    -frazioni

    -i numeri negativi

    -separatore decimale potrebbe differire in paesi (ad esempio,’, ‘ o ‘.’)

    -a volte è permesso di avere un cosiddetto separatore delle migliaia, come uno spazio o una virgola ad esempio 12,324,1000.355

    Per gestire tutti i casi necessari nella vostra applicazione, è necessario essere attenti, ma questa regex copre i tipici scenari (positivo/negativo e frazionari, separati da un punto): ^[-+]?\d*.?\d+$

    Per il test, mi raccomando regexr.com.

  15. 0

    Ecco il mio codice, spero che questo vi aiuterà !

     public boolean isDigitOnly(String text){
    
        boolean isDigit = false;
    
        if (text.matches("[0-9]+") && text.length() > 2) {
            isDigit = true;
        }else {
            isDigit = false;
        }
    
        return isDigit;
    }

Lascia un commento