web-dev-qa-db-fra.com

Regex pour trouver un entier dans une chaîne

J'aimerais utiliser regex avec Java.

Ce que je veux faire, c'est trouver le premier entier d'une chaîne.

Exemple:

String = "the 14 dogs ate 12 bones"

Je reviendrais 14.

String = "djakld;asjl14ajdka;sdj"

Rendrait aussi 14.

C'est ce que j'ai jusqu'ici.

Pattern intsOnly = Pattern.compile("\\d*");
Matcher makeMatch = intsOnly.matcher("dadsad14 dssaf jfdkasl;fj");
makeMatch.find();
String inputInt = makeMatch.group();
System.out.println(inputInt);

Qu'est-ce que je fais mal?

20
mscccc

Vous demandez 0 ou plusieurs chiffres. Vous devez demander 1 ou plus:

"\\d+"
49
Arkadiy

On dirait que les autres solutions n'ont pas réussi à gérer +/- et que des cas comme 2e3, que Java.lang.Integer.parseInt(String) prend en charge, je vais donc essayer de résoudre le problème. Je suis un peu inexpérimenté chez regex, alors j'ai peut-être commis quelques erreurs, utilisé quelque chose que l'analyseur de regex de Java ne prend pas en charge, ou trop compliqué, mais les déclarations semblaient fonctionner dans Kiki 0.5.6 .

Toutes les expressions régulières sont fournies dans un format non échappé pour la lecture et un format échappé que vous pouvez utiliser comme chaîne littérale en Java.

Pour obtenir un octet, short, int ou long d'une chaîne:

unescaped: ([\+-]?\d+)([eE][\+-]?\d+)?
  escaped: ([\\+-]?\\d+)([eE][\\+-]?\\d+)?

... et pour les points bonus ...

Pour obtenir un double ou un float d'une chaîne:

unescaped: ([\+-]?\d(\.\d*)?|\.\d+)([eE][\+-]?(\d(\.\d*)?|\.\d+))?
  escaped: ([\\+-]?\\d(\\.\\d*)?|\\.\d+)([eE][\\+-]?(\\d(\\.\\d*)?|\\.\\d+))?
3
bgw

En plus de ce que PiPeep a dit, si vous essayez de faire correspondre des entiers dans une expression, de sorte que 1 + 2 - 3 ne fera correspondre que 1, 2 et 3, plutôt que 1, + 2 et - 3, vous devez en fait utiliser une instruction lookbehind. la partie que vous souhaitez sera effectivement renvoyée par Matcher.group(2) plutôt que par Matcher.group().

unescaped: ([0-9])?((?(1)(?:[\+-]?\d+)|)(?:[eE][\+-]?\d+)?)
  escaped: ([0-9])?((?(1)(?:[\\+-]?\\d+)|)(?:[eE][\\+-]?\\d+)?)

De plus, pour des choses comme someNumber - 3, où someNumber est un nom de variable ou quelque chose comme ça, vous pouvez utiliser 

unescaped: (\w)?((?(1)(?:[\+-]?\d+)|)(?:[eE][\+-]?\d+)?)
  escaped: (\\w)?((?(1)(?:[\\+-]?\\d+)|)(?:[eE][\\+-]?\\d+)?)

Bien sûr, cela ne fonctionnera pas si vous analysez une chaîne telle que The net change to blahblah was +4

0
AJMansfield

Utilisez l'un d'entre eux:

Pattern intsOnly = Pattern.compile("[0-9]+");

ou

Pattern intsOnly = Pattern.compile("\\d+");
0
Sanjaya Deshapriya

la spécification Java donne en fait à ce monstre une expression rationnelle pour l'analyse des doublons . Cependant, il est considéré comme une mauvaise pratique, juste d'essayer d'analyser avec le type voulu et d'attraper l'erreur a tendance à être légèrement plus lisible.

DOUBLE_PATTERN = Pattern
        .compile("[\\x00-\\x20]*[+-]?(NaN|Infinity|((((\\p{Digit}+)(\\.)?((\\p{Digit}+)?)"
                + "([eE][+-]?(\\p{Digit}+))?)|(\\.((\\p{Digit}+))([eE][+-]?(\\p{Digit}+))?)|"
                + "(((0[xX](\\p{XDigit}+)(\\.)?)|(0[xX](\\p{XDigit}+)?(\\.)(\\p{XDigit}+)))"
                + "[pP][+-]?(\\p{Digit}+)))[fFdD]?))[\\x00-\\x20]*");
0
user3034617

Voici un outil pratique que j'ai créé pour C # avec des génériques. Il correspondra en fonction de votre expression régulière et renverra les types dont vous avez besoin:

public T[] GetMatches<T>(string Input, string MatchPattern) where T : IConvertible
    {
        List<T> MatchedValues = new List<T>();
        Regex MatchInt = new Regex(MatchPattern);

        MatchCollection Matches = MatchInt.Matches(Input);
        foreach (Match m in Matches)
            MatchedValues.Add((T)Convert.ChangeType(m.Value, typeof(T)));

        return MatchedValues.ToArray<T>();
    }

alors si vous voulez ne saisir que les nombres et les retourner dans un tableau de chaînes []:

string Test = "22$data44abc";
string[] Matches = this.GetMatches<string>(Test, "\\d+");

Espérons que cela soit utile à quelqu'un ...

0
Chris Smith