web-dev-qa-db-fra.com

Java String - Vérifie si une chaîne de caractères ne contient que des chiffres et non des lettres

J'ai une chaîne que je charge tout au long de ma candidature et qui passe de chiffres en lettres et autres. J'ai une simple déclaration if pour voir si elle contient des lettres ou des chiffres, mais quelque chose ne fonctionne pas correctement. Voici un extrait.

String text = "abc"; 
String number; 

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

Bien que la variable text contienne des lettres, la condition est retournée sous la forme true. Et && doivent être considérés comme deux conditions devant être true pour pouvoir traiter le number = text;

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

Solution:

J'ai pu résoudre ce problème en utilisant le code suivant fourni par un commentaire sur cette question. Tous les autres articles sont également valables!

Ce que j'ai utilisé qui a fonctionné est venu du premier commentaire. Bien que tous les exemples de codes fournis semblent également valables!

String text = "abc"; 
String number; 

if (Pattern.matches("[a-zA-Z]+", text) == false && text.length() > 2) {
    number = text; 
}
164
RedHatcc

Si vous traitez le nombre sous forme de texte, changez alors:

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

à:

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

Au lieu de vérifier que la chaîne ne contient pas de caractères alphabétiques, vérifiez qu'elle ne contient que numérique.

Si vous voulez réellement utiliser la valeur numérique, utilisez Integer.parseInt() ou Double.parseDouble() comme d'autres l'ont expliqué ci-dessous.


En remarque, il est généralement considéré comme une mauvaise pratique de comparer les valeurs booléennes à true ou false. Utilisez simplement if (condition) ou if (!condition).

315
Adam Liss

Vous pouvez également utiliser NumberUtil.isCreatable (String str) d'Apache Commons

20
Dhrumil Shah

Voici comment je le ferais:

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

Le $ évitera une correspondance partielle, par exemple; 1B.

12
tokhi

Sur le plan des performances, parseInt et ces solutions sont beaucoup plus graves que d’autres solutions, car elles nécessitent au moins une gestion des exceptions.

J'ai effectué des tests jmh et constaté que l'itération sur String avec charAt et la comparaison de caractères avec des caractères de limite sont le moyen le plus rapide de vérifier si string ne contient que des chiffres.

Test JMH

Les tests comparent les performances de Character.isDigit par rapport à Pattern.matcher().matches par rapport à Long.parseLong par rapport à la vérification des valeurs de caractère.

Ces méthodes peuvent produire des résultats différents pour les chaînes non-ASCII et les chaînes contenant les signes +/-.

Les tests sont exécutés en mode débit (plus grand est le mieux) avec 5 itérations d’échauffement et 5 itérations de test.

Résultats

Notez que parseLong est presque 100 fois plus lent que isDigit pour le premier test de charge.

## 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 de tests

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

Mis à jour le 23 février 2018

  • Ajoutez deux autres cas - un en utilisant charAt au lieu de créer un tableau supplémentaire et un autre en utilisant IntStream des codes de caractères
  • Ajouter une pause immédiate si aucun chiffre n'est trouvé pour les tests en boucle
  • Renvoie false pour une chaîne vide pour les tests en boucle.

Mis à jour le 23 février 2018

  • Ajoutez un cas de test supplémentaire (le plus rapide!) Qui compare la valeur de caractère sans utiliser le flux
7
Anton R

Apache Commons Lang fournit org.Apache.commons.lang.StringUtils.isNumeric(CharSequence cs) , qui prend comme argument un String et vérifie si elle est purement numérique des caractères (y compris des nombres tirés de scripts non latins). Cette méthode retourne false s'il existe des caractères tels que des séparateurs d'espace, moins, plus et décimaux tels que virgule et point.

D'autres méthodes de cette classe permettent des vérifications numériques supplémentaires.

2
Abdull

boolean isNum = text.chars (). allMatch (c -> c> = 48 && c <= 57)

2
Andy

Il existe de nombreuses possibilités pour obtenir des nombres de Strings dans Java (et inversement). Vous voudrez peut-être ignorer la partie regex pour vous épargner la complication.

Par exemple, vous pouvez essayer de voir ce que Double.parseDouble(String s) retourne pour vous. Il devrait lancer un NumberFormatException s'il ne trouve pas de valeur appropriée dans la chaîne. Je suggérerais cette technique car vous pourriez en fait utiliser la valeur représentée par le String sous forme de type numérique.

1
pseudoramble

Vous pouvez utiliser Regex.Match

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

Ou vous pouvez utiliser des versions telles que Integer.parseInt(String) ou mieux Long.parseLong(String) pour les grands nombres, comme par exemple:

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

Et puis testez avec:

if (onlyContainsNumbers(text) && text.length() > 2) {
    // do Stuff
}
1
Lag

Les expressions rationnelles ci-dessous peuvent être utilisées pour vérifier si une chaîne a seulement un nombre ou pas:

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

Les deux conditions ci-dessus renverront true si String contient des non-nombres. Sur false, la chaîne ne comporte que des chiffres.

1
Nitesh Shrivastava

Pour vérifier simplement la chaîne contenant uniquement ALPHABETS, utilisez le code suivant:

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

Afin de vérifier simplement la chaîne contenant seulement NUMBER, utilisez le code suivant:

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

J'espère que cela aidera à quelqu'un!

1

Ce code est déjà écrit. Si cela ne vous dérange pas de la performance (extrêmement) mineure - ce qui n’est probablement pas pire que de faire un match regex - utilisez Integer.parseInt () ou Double.parseDouble () . Cela vous dira tout de suite si une chaîne ne contient que des nombres (ou est un nombre, selon le cas). Si vous devez gérer des chaînes de chiffres plus longues, les constructeurs sport BigInteger et BigDecimal acceptent les chaînes. N'importe lequel d'entre eux jettera un NumberFormatException si vous essayez de lui passer un non-nombre (entier ou décimal, en fonction de celui que vous avez choisi, bien sûr). Sinon, en fonction de vos besoins, il suffit de modifier les caractères de la chaîne et de vérifier Character.isDigit () et/ou Character.isLetter () .

0
Ryan Stewart

Il est déconseillé d'impliquer une exception lors de la projection/manipulation dans un tel scénario typique.

Par conséquent, un parseInt () n’est pas Nice, mais une expression rationnelle est une solution élégante pour cela, mais prenez soin de ce qui suit:
- fractions
- nombres négatifs
- Le séparateur décimal peut différer selon les pays (p. ex. ',' ou '.')
- il est parfois permis d’utiliser un séparateur de milliers, comme un espace ou une virgule, par exemple. 12 324,1000,355

Pour gérer tous les cas nécessaires dans votre application, vous devez faire attention, mais cette expression régulière couvre les scénarios typiques (positif/négatif et fractionnel, séparés par un point): ^ [- +]?\D *.?\D + $
Pour les tests, je recommande regexr.com .

0
Adam Bodrogi
Character first_letter_or_number = query.charAt(0);
                //------------------------------------------------------------------------------
                if (Character.isDigit())
                {

                }
                else if (Character.isLetter())
                {

                }
0
JamisonMan111

Exemple de test de travail

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

Néanmoins, votre code peut être cassé par "1a", etc. vous devez donc vérifier les exceptions.

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

Méthode de vérification de non chaîne ou non

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

Voici mon code, espérons que cela vous aidera!

 public boolean isDigitOnly(String text){

    boolean isDigit = false;

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

    return isDigit;
}
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;
    }
}
0
Usman Javaid