web-dev-qa-db-fra.com

Python regex pour entier?

J'apprends l'expression régulière et je voudrais utiliser une expression régulière dans Python pour définir uniquement des entiers - des nombres entiers mais pas des décimales.

Je pourrais en créer un qui n'autorise que les chiffres en utilisant \d, mais il autorise également les nombres décimaux, ce que je ne veux pas:

price = TextField(_('Price'), [
    validators.Regexp('\d', message=_('This is not an integer number, please see the example and try again')),
    validators.Optional()]) 

Comment puis-je changer le code en niquement autoriser les entiers?

23
Niklas Rosencrantz

Regexp fonctionne sur la base des caractères et \d signifie un seul chiffre 0...9 et non un nombre décimal.

Une expression régulière qui ne correspond qu'à des entiers avec un signe pourrait être par exemple

^[-+]?[0-9]+$

sens

  1. ^ - début de chaîne
  2. [-+]? - une option (c'est ce que ? signifie) signe moins ou plus
  3. [0-9]+ - un ou plusieurs chiffres (le plus signifie "un ou plusieurs" et [0-9] est une autre façon de dire \d)
  4. $ - fin de chaîne

Remarque: avoir le signe considéré comme faisant partie du nombre n'est correct que si vous avez besoin d'analyser juste le nombre. Pour les analyseurs plus généraux gérant les expressions, il est préférable de laisser le signe hors du nombre: les flux source comme 3-2 pourrait autrement finir par être analysé comme une séquence de deux entiers au lieu d'un entier, d'un opérateur et d'un autre entier. D'après mon expérience, les nombres négatifs sont mieux gérés par un pliage constant de l'opérateur de négation unaire à un niveau supérieur.

78
6502

Vous devez ancrer l'expression régulière au début et à la fin de la chaîne:

^[0-9]+$

Explication:

^      # Start of string
[0-9]+ # one or more digits 0-9
$      # End of string
13
Tim Pietzcker

Vous utilisez apparemment Django.

Il vaut probablement mieux utiliser simplement models.IntegerField() au lieu de models.TextField(). Non seulement il fera la vérification pour vous, mais il vous donnera le message d'erreur traduit en plusieurs langues, et il convertira la valeur de son type dans la base de données vers le type de votre Python coder de manière transparente.

8
e-satis

Je préfère ^[-+]?([1-9]\d*|0)$ parce que ^[-+]?[0-9]+$ autorise la chaîne commençant par 0.

RE_INT = re.compile(r'^[-+]?([1-9]\d*|0)$')


class TestRE(unittest.TestCase):
    def test_int(self):
        self.assertFalse(RE_INT.match('+'))
        self.assertFalse(RE_INT.match('-'))

        self.assertTrue(RE_INT.match('1'))
        self.assertTrue(RE_INT.match('+1'))
        self.assertTrue(RE_INT.match('-1'))
        self.assertTrue(RE_INT.match('0'))
        self.assertTrue(RE_INT.match('+0'))
        self.assertTrue(RE_INT.match('-0'))

        self.assertTrue(RE_INT.match('11'))
        self.assertFalse(RE_INT.match('00'))
        self.assertFalse(RE_INT.match('01'))
        self.assertTrue(RE_INT.match('+11'))
        self.assertFalse(RE_INT.match('+00'))
        self.assertFalse(RE_INT.match('+01'))
        self.assertTrue(RE_INT.match('-11'))
        self.assertFalse(RE_INT.match('-00'))
        self.assertFalse(RE_INT.match('-01'))

        self.assertTrue(RE_INT.match('1234567890'))
        self.assertTrue(RE_INT.match('+1234567890'))
        self.assertTrue(RE_INT.match('-1234567890'))
2
sira