Java String - voir si une chaîne de caractères ne contient que des nombres et non des lettres

j'ai une chaîne que je charge tout au long de ma demande, et il change 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 tout à fait correctement. Voici un extrait de code.

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 retourne comme true . Le et && devrait être évalué comme les deux conditions devant être true afin de 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 postes sont valables aussi bien!

ce que j'ai utilisé qui a fonctionné est issu du premier commentaire. Bien que tous les codes d'exemple fournis semblent être valables aussi!

String text = "abc"; 
String number; 

if (Pattern.matches("[a-zA-Z]+", text) == false && text.length() > 2) {
    number = text; 
}
145
demandé sur ROMANIA_engineer 2012-05-14 02:05:37

16 réponses

si vous traitez le numéro comme texte, puis changer:

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 ne contient pas de caractères alphabétiques, vérifiez pour être sûr qu'elle contient seulement numerics.

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


comme note latérale, il est généralement considéré comme une mauvaise pratique de comparer les valeurs booléennes à true ou false . Il suffit d'utiliser if (condition) ou if (!condition) .

277
répondu Adam Liss 2015-01-08 13:34:22

vous pouvez également utiliser NumberUtil.isCreatable (String) from Apache Commons

20
répondu Dhrumil Shah 2017-12-21 16:17:35

C'est comment j'allais le faire:

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

le $ évitera une correspondance partielle E. g; 1B .

8
répondu tokhi 2016-09-16 12:05:54

Performance-wise parseInt et tels sont beaucoup plus worser que d'autres solutions, parce qu'au moins exigent la manipulation d'exception.

j'ai effectué des tests jmh et j'ai trouvé que l'itération sur la chaîne de caractères en utilisant charAt et en comparant les caractères avec les caractères limites est le moyen le plus rapide de tester si la chaîne de caractères ne contient que des chiffres.

JMH testing

Tests de comparer les performances des Character.isDigit vs Pattern.matcher().matches vs Long.parseLong vs vérification des valeurs de char.

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

Essais exécutés en mode de débit ( plus grand est mieux ) avec 5 itérations d'échauffement et 5 itérations d'essai.

résultats

noter que parseLong est presque 100 fois plus lent que isDigit pour la première charge d'essai.

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

Test suite

@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

  • ajouter deux cas supplémentaires - un en utilisant charAt au lieu de créer un tableau supplémentaire et un autre en utilisant IntStream de codes de caractères
  • ajouter rupture immédiate si aucun chiffre n'a été trouvé pour les cas d'essai en boucle
  • Return false pour une chaîne vide pour la boucle en cas de test

mis à jour le 23 février 2018

  • Ajouter un cas d'essai de plus (le plus rapide!) qui compare la valeur de char sans utiliser stream
4
répondu Anton R 2018-02-26 15:55:32

il existe de nombreuses possibilités pour obtenir des numéros de String s en Java (et vice versa). Vous pouvez ignorer les regex partie de vous épargner la complication.

par exemple, vous pouvez essayer et voir ce que Double.parseDouble(String s) retourne pour vous. Il faut jeter un NumberFormatException s'il ne trouve pas une valeur appropriée dans la chaîne. Je suggère cette technique parce que vous pouvez réellement faire usage de la valeur représentée par le String en tant que type numérique.

1
répondu Doug Swain 2012-05-13 22:13:37

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

1
répondu Andy 2017-01-27 22:33:56

vous pouvez utiliser Regex.Match

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

ou vous pouvez utiliser des versions comme Integer.parseInt(String) ou mieux Long.parseLong(String) pour des nombres plus grands comme par exemple:

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

et ensuite tester avec:

if (onlyContainsNumbers(text) && text.length() > 2) {
    // do Stuff
}
1
répondu Lag 2017-02-01 13:52:05

Apache Commons Lang provides org.apache.commons.lang.StringUtils.isNumeric(CharSequence cs) , qui prend comme argument un String et vérifie s'il se compose de caractères purement numériques (y compris les nombres de caractères non latins). Cette méthode retourne false s'il y a des caractères comme espace, moins, plus, et des séparateurs décimaux comme virgule et point.

D'autres méthodes de cette classe permettent d'autres vérifications numériques.

1
répondu Abdull 2018-02-01 12:42:41

pour vérifier simplement la chaîne qu'elle contient seulement des ALPHABETS utilisez le code suivant:

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

pour vérifier simplement la chaîne de caractères QU'elle ne contient que le numéro, utilisez le code suivant :

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

Espérons que cela aidera à quelqu'un!

1
répondu Aman Gupta 2018-05-01 08:36:45

ce code est déjà écrit. Si vous ne faites pas attention à la performance (extrêmement) mineure hit--qui n'est probablement pas pire que de faire une correspondance regex--utilisez entier.parseInt() ou Double.parseDouble () . Cela vous dira tout de suite si une chaîne de caractères n'est que des nombres (ou est un nombre , selon le cas). Si vous avez besoin de manipuler des chaînes de nombres plus longues, à la fois BigInteger et BigDecimal les constructeurs sportifs qui acceptent les cordes. N'importe lequel de ceux-ci lancera un NumberFormatException si vous essayez de lui passer un non-nombre (intégrale ou décimale, basée sur celle que vous choisissez, bien sûr). Alternativement, selon vos besoins, il suffit d'itérer les caractères dans la chaîne et de cocher caractère.Isdigit () et/ou .isLetter () .

0
répondu Ryan Stewart 2012-05-13 22:15:28
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
répondu Usman Javaid 2016-12-01 08:03:48

ci-dessous regexs peut être utilisé pour vérifier si une chaîne a seulement le nombre ou pas:

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

les deux conditions ci-dessus retourneront true si la chaîne contient des non-nombres. Sur false , la chaîne n'a que des nombres.

0
répondu Nitesh Shrivastava 2017-04-17 00:22:56
Character first_letter_or_number = query.charAt(0);
                //------------------------------------------------------------------------------
                if (Character.isDigit())
                {

                }
                else if (Character.isLetter())
                {

                }
0
répondu JamisonMan111 2017-12-29 01:07:51

exemple D'essai de fonctionnement

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

toujours votre code peut être cassé par " 1a "etc donc vous devez vérifier l'exception

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 la chaîne de caractères no is

private boolean isStringContainsNumber(String s) {
        Pattern p = Pattern.compile("[0-9]");
        Matcher m = p.matcher(s);
        return m.find();
    }
0
répondu vaquar khan 2018-05-17 20:58:46

c'est une mauvaise pratique d'inclure toute exception de lancer/manipulation dans un tel scénario typique.



par conséquent un parseInt () n'est pas agréable, mais un regex est une solution élégante pour cela, mais prendre soin de ce qui suit:

- fractions

- nombres négatifs

- le séparateur décimal peut différer dans le contenu (par exemple", "ou".')

-parfois, il est autorisé à avoir un séparateur de milliers, comme un espace ou une virgule Par exemple 12,324,1000.355

pour traiter tous les cas nécessaires dans votre application, vous devez être prudent, mais ce regex couvre les scénarios typiques (positif / négatif et fractionnaire, séparé par un point): ^[ -+]?\d*.?\d+$

pour les tests, je recommande regexr.com .

0
répondu Adam Bodrogi 2018-09-02 20:05:25

Voici mon code, j'espère 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
répondu Saurabh Gaddelpalliwar 2018-09-27 11:56:42