117 votes

Expression régulière pour faire correspondre les nombres avec ou sans virgule et les décimales dans un texte

J'essaie de localiser et de remplacer tous les chiffres dans un corps de texte. J'ai trouvé quelques exemples de regex, qui résolvent presque le problème, mais aucun n'est encore parfait. Le problème que j'ai est que les chiffres dans mon texte peuvent ou non avoir des décimales et des virgules. Par exemple :

"Le renard de 5000 livres a sauté par-dessus une clôture de 99,999.99998713 pieds."

La regex doit retourner " 5000 " et " 99,999.99998713 ". Les exemples que j'ai trouvés cassent les chiffres sur la virgule ou sont limités à deux décimales. Je commence à comprendre suffisamment les regex pour comprendre pourquoi certains exemples sont limités à deux décimales, mais je n'ai pas encore appris à surmonter ce problème et à inclure la virgule pour obtenir la séquence complète.

Voici ma dernière version :

[0-9]+(\.[0-9][0-9]?)?

Qui renvoie, " 5000 ", " 99,99 ", " 9.99 ", et " 998713 " pour le texte ci-dessus.

2 votes

Quel langage de programmation ou quelle saveur de regex ?

7 votes

Il semble que presque toutes les réponses ici font l'erreur de permettre des choses comme .,.,. ou 9,9,9,9 ou 9,9.99.9 . Ces regex n'exigent pas que les nombres soient dans le bon format, et au pire, traitera la ponctuation comme des chiffres. Il est possible d'apporter quelques modifications facultatives (par exemple, autoriser ou non les zéros de tête et de queue), mais certaines des réponses que je vois sont carrément incorrectes. Je n'aime pas vraiment les votes négatifs, surtout pour les tentatives honnêtes, mais j'ai l'impression que les réponses ont besoin d'être nettoyées. Cette question est courante et sera certainement posée à nouveau.

0 votes

Au cas où vous ne le connaîtriez pas, jetez un coup d'oeil à regexpal.com

333voto

Justin Morgan Points 12853

EDIT : Puisque ce sujet a été vu par beaucoup de personnes, laissez-moi commencer par donner à tout le monde ce qu'ils ont cherché sur Google :

#ALL THESE REQUIRE THE WHOLE STRING TO BE A NUMBER
#For numbers embedded in sentences, see discussion below

#### NUMBERS AND DECIMALS ONLY ####
#No commas allowed
#Pass: (1000.0), (001), (.001)
#Fail: (1,000.0)
^\d*\.?\d+$

#No commas allowed
#Can't start with "."
#Pass: (0.01)
#Fail: (.01)
^(\d+\.)?\d+$

#### CURRENCY ####
#No commas allowed
#"$" optional
#Can't start with "."
#Either 0 or 2 decimal digits
#Pass: ($1000), (1.00), ($0.11)
#Fail: ($1.0), (1.), ($1.000), ($.11)
^\$?\d+(\.\d{2})?$

#### COMMA-GROUPED ####
#Commas required between powers of 1,000
#Can't start with "."
#Pass: (1,000,000), (0.001)
#Fail: (1000000), (1,00,00,00), (.001)
^\d{1,3}(,\d{3})*(\.\d+)?$

#Commas required
#Cannot be empty
#Pass: (1,000.100), (.001)
#Fail: (1000), ()
^(?=.)(\d{1,3}(,\d{3})*)?(\.\d+)?$

#Commas optional as long as they're consistent
#Can't start with "."
#Pass: (1,000,000), (1000000)
#Fail: (10000,000), (1,00,00)
^(\d+|\d{1,3}(,\d{3})*)(\.\d+)?$

#### LEADING AND TRAILING ZEROES ####
#No commas allowed
#Can't start with "."
#No leading zeroes in integer part
#Pass: (1.00), (0.00)
#Fail: (001)
^([1-9]\d*|0)(\.\d+)?$

#No commas allowed
#Can't start with "."
#No trailing zeroes in decimal part
#Pass: (1), (0.1)
#Fail: (1.00), (0.1000)
^\d+(\.\d*[1-9])?$

Maintenant que cela a été dit, la majeure partie de ce qui suit se veut un commentaire sur la complexité des expressions rationnelles si vous essayez de les utiliser intelligemment, et sur les raisons pour lesquelles vous devriez chercher des alternatives. Lisez à vos risques et périls.


Il s'agit d'une tâche très courante, mais toutes les réponses que j'ai vues ici jusqu'à présent acceptent des entrées qui ne correspondent pas à votre format numérique, telles que ,111 , 9,9,9 ou encore .,,. . C'est assez simple à corriger, même si les chiffres sont intégrés dans un autre texte. Je pense que tout ce qui n'arrive pas à sortir 1 234,56 et 1234- et seulement ces chiffres -sans abc22 1,234.56 9.9.9.9 def 1234 est une mauvaise réponse.

Tout d'abord, si vous n'avez pas besoin de faire tout cela en une seule regex, ne le faites pas. Une seule regex pour deux formats de chiffres différents est difficile à maintenir, même s'ils ne sont pas intégrés à d'autres textes. Ce que vous devriez faire, c'est diviser le tout sur les espaces, puis exécuter deux ou trois regex plus petites sur les résultats. Si ce n'est pas une option pour vous, continuez à lire.

Modèle de base

En tenant compte des exemples que vous avez donnés, voici une simple regex qui autorise pratiquement tous les nombres entiers ou décimaux dans 0000 et bloque tout le reste :

^\d*\.?\d+$

En voici un qui nécessite 0,000 format :

^\d{1,3}(,\d{3})*(\.\d+)?$

Mettez-les ensemble, et les virgules deviennent facultatives tant qu'elles sont cohérentes :

^(\d*\.?\d+|\d{1,3}(,\d{3})*(\.\d+)?)$

Numéros incorporés

Les modèles ci-dessus requièrent que l'entrée entière soit un nombre. Vous recherchez des nombres intégrés dans du texte, vous devez donc assouplir cette partie. D'un autre côté, vous ne voulez pas qu'il voit catch22 et pense avoir trouvé le numéro 22. Si vous utilisez quelque chose qui supporte le lookbehind (comme .NET), c'est assez facile : remplacez ^ avec (?<!\S) et $ avec (?!\S) et vous êtes prêt à partir :

(?<!\S)(\d*\.?\d+|\d{1,3}(,\d{3})*(\.\d+)?)(?!\S)

Si vous travaillez avec JavaScript ou Ruby ou autre, les choses commencent à être plus complexes :

(?:^|\s)(\d*\.?\d+|\d{1,3}(?:,\d{3})*(?:\.\d+)?)(?!\S)

Vous devrez utiliser des groupes de capture ; je ne vois pas d'autre solution sans le support de Lookbehind. Les numéros que vous voulez seront dans le groupe 1 (en supposant que tout le match est dans le groupe 0).

Validation et règles plus complexes

Je pense que cela couvre votre question, donc si c'est tout ce dont vous avez besoin, arrêtez de lire maintenant. Si vous voulez devenir plus sophistiqué, les choses deviennent très complexes très rapidement. En fonction de votre situation, vous voudrez peut-être bloquer tout ou partie des éléments suivants :

  • Entrée vide
  • Zéros non significatifs (par exemple 000123)
  • Zéros de fin (par exemple 1,2340000)
  • Décimales commençant par le point décimal (par exemple, .001 par opposition à 0.001)

Pour l'anecdote, supposons que vous voulez bloquer les trois premiers, mais autoriser le dernier. Que devez-vous faire ? Je vais vous dire ce que vous devez faire, vous devez utiliser une regex différente pour chaque règle et réduire progressivement vos correspondances. Mais pour le bien du défi, voici comment faire tout cela en un seul motif géant :

(?<!\S)(?=.)(0|([1-9](\d*|\d{0,2}(,\d{3})*)))?(\.\d*[1-9])?(?!\S)

Et voici ce que cela signifie :

(?<!\S) to (?!\S) #The whole match must be surrounded by either whitespace or line boundaries. So if you see something bogus like :;:9.:, ignore the 9.
(?=.)             #The whole thing can't be blank.

(                    #Rules for the integer part:
  0                  #1. The integer part could just be 0...
  |                  #
  [1-9]              #   ...otherwise, it can't have leading zeroes.
  (                  #
    \d*              #2. It could use no commas at all...
    |                #
    \d{0,2}(,\d{3})* #   ...or it could be comma-separated groups of 3 digits each.
  )                  # 
)?                   #3. Or there could be no integer part at all.

(       #Rules for the decimal part:
  \.    #1. It must start with a decimal point...
  \d*   #2. ...followed by a string of numeric digits only.
  [1-9] #3. It can't be just the decimal point, and it can't end in 0.
)?      #4. The whole decimal part is also optional. Remember, we checked at the beginning to make sure the whole thing wasn't blank.

Testé ici : http://rextester.com/YPG96786

Cela permettra des choses comme :

100,000
999.999
90.0009
1,000,023.999
0.111
.111
0

Il bloquera des choses comme :

1,1,1.111
000,001.111
999.
0.
111.110000
1.1.1.111
9.909,888

Il existe plusieurs façons de rendre cette regex plus simple et plus courte, mais comprenez que le fait de changer le motif va assouplir ce qu'elle considère comme un nombre.

Étant donné que de nombreux moteurs regex (JavaScript et Ruby, par exemple) ne prennent pas en charge le lookbehind négatif, la seule façon de procéder correctement est d'utiliser des groupes de capture :

(:?^|\s)(?=.)((?:0|(?:[1-9](?:\d*|\d{0,2}(?:,\d{3})*)))?(?:\.\d*[1-9])?)(?!\S)

Les chiffres que vous recherchez seront dans le groupe de capture 1.

Testé ici : http://rubular.com/r/3HCSkndzhT

Une dernière remarque

Évidemment, c'est une regex massive, compliquée et illisible. J'ai apprécié le défi, mais vous devriez demandez-vous si vous voulez vraiment l'utiliser dans un environnement de production. Au lieu d'essayer de tout faire en une seule étape, vous pourriez le faire en deux : une regex pour attraper tout ce qui est pourrait être un nombre, puis un autre pour éliminer tout ce qui est n'est pas un numéro. Vous pouvez également effectuer un traitement de base, puis utiliser les fonctions intégrées d'analyse des nombres de votre langue. À vous de choisir.

2 votes

C'est une très bonne tentative, mais il peut y avoir un problème avec elle - en fonction de l'avidité du moteur, un nombre donné peut correspondre partiellement à deux des formats concurrents, au lieu de correspondre individuellement au bon format - c'est-à-dire que 5000 peut donner 500 plus 0. Cela me rend un peu sceptique quant à la tentative de couvrir trop de choses avec une seule expression, et c'est pourquoi j'ai donné une réponse plus simple avec la mise en garde contre les faux positifs possibles. En fin de compte, c'est la rigueur des exigences qui doit dicter la solution.

0 votes

@entonio - C'est un bon point. Cela pourrait fonctionner avec la dernière édition. D'ailleurs, votre downvote ne venait pas de moi, puisque vous avez signalé la correspondance potentielle 1,11,11.

0 votes

J'utilise ActionScript, qui se comporte, je crois, de la même manière que JavaScript. En utilisant le premier motif que vous avez recommandé, j'obtiens les résultats suivants sur ma chaîne de test (Pour la validation, je renvoie simplement les correspondances enveloppées dans "<<[résultat]>>") : Le< 5>>>renard de 1000 livres a sauté par-dessus une< 9>>9<<,9>><<99>><<.9>><<99>><98>><<71>> clôture de 3 pieds.

12voto

Leons Points 1966

L'expression rationnelle ci-dessous correspondra aux deux chiffres de votre exemple.

\b\d[\d,.]*\b

Il retournera 5000 et 99,999.99998713 - correspondant à vos exigences.

3 votes

Cela correspondra à la virgule dans this,that .

0 votes

@Justin Morgan - vous avez raison, je n'ai pas testé cette condition. Voici une version mise à jour qui fonctionnera pour tous les cas, sauf pour un nombre commençant par une virgule ou un point. \b\d[\d,.]+\b

0 votes

Bien mieux, mais ça permettra toujours 9....9 ou 1,,,,X (bien que le X ne soit pas inclus dans le match).

11voto

eyquem Points 9942

Il y a quelques jours, j'ai travaillé sur le problème de la suppression des zéros de queue de la chaîne d'un nombre .

Dans la continuité de ce problème, je trouve celui-ci intéressant car il élargit le problème aux nombres comportant des virgules.

J'ai pris le modèle de regex que j'avais écrit dans le problème précédent sur lequel j'ai travaillé et je l'ai amélioré afin qu'il puisse traiter les nombres avec des virgules comme une réponse pour ce problème.

Je me suis laissé emporter par mon enthousiasme et mon goût pour les regex. Je ne sais pas si le résultat correspond exactement au besoin exprimé par Michael Prescott. Je serais intéressé de connaître les points qui sont en excès ou en manque dans ma regex, et de la corriger pour qu'elle vous convienne mieux.

Maintenant, après une longue session de travail sur cette regex, j'ai une sorte de poids dans le cerveau, donc je ne suis pas assez frais pour donner beaucoup d'explications. Si des points sont obscurs, et si quelqu'un peut être suffisamment intéressé, s'il vous plaît, demandez-le moi.

La regex est construite de manière à pouvoir détecter les nombres exprimés en notation scientifique. 2E10 ou même 5,22,454.12E-00.0478 en supprimant les zéros inutiles dans les deux parties de ces chiffres également. Si un exposant est égal à zéro, le nombre est modifié de manière à ce qu'il n'y ait plus d'exposant.

J'ai mis des vérifications dans le modèle pour que certains cas particuliers ne correspondent pas, par exemple '12..57' ne correspondra pas. Mais en ',111' la chaîne '111' correspond parce que la virgule précédente est considérée comme une virgule n'étant pas dans un nombre mais une virgule de phrase.

Je pense que la gestion des virgules devrait être améliorée, car il me semble qu'il n'y a que 2 chiffres entre les virgules dans la numérotation indienne. Ce ne sera pas difficile à corriger, je présume.

Voici un code démontrant le fonctionnement de ma regex. Il y a deux fonctions, selon que l'on veut les nombres '.1245' pour être transformé en '0.1245' ou non. Je ne serais pas surpris que des erreurs ou des appariements ou désappariements non désirés subsistent pour certains cas de chaînes de chiffres ; j'aimerais alors connaître ces cas pour comprendre et corriger la déficience.

Je m'excuse pour ce code écrit en Python, mais les regex sont trans-langage et je pense que tout le monde sera capable de comprendre le modèle de reex.

import re

regx = re.compile('(?<![\d.])(?!\.\.)(?<![\d.][eE][+-])(?<![\d.][eE])(?<!\d[.,])'
                  '' #---------------------------------
                  '([+-]?)'
                  '(?![\d,]*?\.[\d,]*?\.[\d,]*?)'
                  '(?:0|,(?=0)|(?<!\d),)*'
                  '(?:'
                  '((?:\d(?!\.[1-9])|,(?=\d))+)[.,]?'
                  '|\.(0)'
                  '|((?<!\.)\.\d+?)'
                  '|([\d,]+\.\d+?))'
                  '0*'
                  '' #---------------------------------
                  '(?:'
                  '([eE][+-]?)(?:0|,(?=0))*'
                  '(?:'
                  '(?!0+(?=\D|\Z))((?:\d(?!\.[1-9])|,(?=\d))+)[.,]?'
                  '|((?<!\.)\.(?!0+(?=\D|\Z))\d+?)'
                  '|([\d,]+\.(?!0+(?=\D|\Z))\d+?))'
                  '0*'
                  ')?'
                  '' #---------------------------------
                  '(?![.,]?\d)')

def dzs_numbs(x,regx = regx): # ds = detect and zeros-shave
    if not regx.findall(x):
        yield ('No match,', 'No catched string,', 'No groups.')
    for mat in regx.finditer(x):
        yield (mat.group(), ''.join(mat.groups('')), mat.groups(''))

def dzs_numbs2(x,regx = regx): # ds = detect and zeros-shave
    if not regx.findall(x):
        yield ('No match,', 'No catched string,', 'No groups.')
    for mat in regx.finditer(x):
        yield (mat.group(),
               ''.join(('0' if n.startswith('.') else '')+n for n in mat.groups('')),
               mat.groups(''))

NS = ['  23456000and23456000. or23456000.000  00023456000 s000023456000.  000023456000.000 ',
      'arf 10000 sea10000.+10000.000  00010000-00010000. kant00010000.000 ',
      '  24:  24,  24.   24.000  24.000,   00024r 00024. blue 00024.000  ',
      '  8zoom8.  8.000  0008  0008. and0008.000  ',
      '  0   00000M0. = 000.  0.0  0.000    000.0   000.000   .000000   .0   ',
      '  .0000023456    .0000023456000   '
      '  .0005872    .0005872000   .00503   .00503000   ',
      '  .068    .0680000   .8   .8000  .123456123456    .123456123456000    ',
      '  .657   .657000   .45    .4500000   .7    .70000  0.0000023230000   000.0000023230000   ',
      '  0.0081000    0000.0081000  0.059000   0000.059000     ',
      '  0.78987400000 snow  00000.78987400000  0.4400000   00000.4400000   ',
      '  -0.5000  -0000.5000   0.90   000.90   0.7   000.7   ',
      '  2.6    00002.6   00002.60000  4.71   0004.71    0004.7100   ',
      '  23.49   00023.49   00023.490000  103.45   0000103.45   0000103.45000    ',
      '  10003.45067   000010003.45067   000010003.4506700 ',
      '  +15000.0012   +000015000.0012   +000015000.0012000    ',
      '  78000.89   000078000.89   000078000.89000    ',
      '  .0457e10   .0457000e10   00000.0457000e10  ',
      '   258e8   2580000e4   0000000002580000e4   ',
      '  0.782e10   0000.782e10   0000.7820000e10  ',
      '  1.23E2   0001.23E2  0001.2300000E2   ',
      '  432e-102  0000432e-102   004320000e-106   ',
      '  1.46e10and0001.46e10  0001.4600000e10   ',
      '  1.077e-300  0001.077e-300  0001.077000e-300   ',
      '  1.069e10   0001.069e10   0001.069000e10   ',
      '  105040.03e10  000105040.03e10  105040.0300e10    ',
      '  +286E000024.487900  -78.4500e.14500   .0140E789.  ',
      '  081,12.40E07,95.0120     0045,78,123.03500e-0.00  ',
      '  0096,78,473.0380e-0.    0008,78,373.066000E0.    0004512300.E0000  ',
      '  ..18000  25..00 36...77   2..8  ',
      '  3.8..9    .12500.     12.51.400  ',
      '  00099,111.8713000   -0012,45,83,987.26+0.000,099,88,44.or00,00,00.00must',
      '  00099,44,and   0000,099,88,44.bom',
      '00,000,00.587000  77,98,23,45.,  this,that ',
      '  ,111  145.20  +9,9,9  0012800  .,,.  1  100,000 ',
      '1,1,1.111  000,001.111   -999.  0.  111.110000  1.1.1.111  9.909,888']

for ch in NS:
    print 'string: '+repr(ch)
    for strmatch, modified, the_groups in dzs_numbs2(ch):
        print strmatch.rjust(20),'',modified,'',the_groups
    print

résultat

string: '  23456000and23456000. or23456000.000  00023456000 s000023456000.  000023456000.000 '
            23456000  23456000  ('', '23456000', '', '', '', '', '', '', '')
           23456000.  23456000  ('', '23456000', '', '', '', '', '', '', '')
        23456000.000  23456000  ('', '23456000', '', '', '', '', '', '', '')
         00023456000  23456000  ('', '23456000', '', '', '', '', '', '', '')
       000023456000.  23456000  ('', '23456000', '', '', '', '', '', '', '')
    000023456000.000  23456000  ('', '23456000', '', '', '', '', '', '', '')

string: 'arf 10000 sea10000.+10000.000  00010000-00010000. kant00010000.000 '
               10000  10000  ('', '10000', '', '', '', '', '', '', '')
              10000.  10000  ('', '10000', '', '', '', '', '', '', '')
           10000.000  10000  ('', '10000', '', '', '', '', '', '', '')
            00010000  10000  ('', '10000', '', '', '', '', '', '', '')
           00010000.  10000  ('', '10000', '', '', '', '', '', '', '')
        00010000.000  10000  ('', '10000', '', '', '', '', '', '', '')

string: '  24:  24,  24.   24.000  24.000,   00024r 00024. blue 00024.000  '
                  24  24  ('', '24', '', '', '', '', '', '', '')
                 24,  24  ('', '24', '', '', '', '', '', '', '')
                 24.  24  ('', '24', '', '', '', '', '', '', '')
              24.000  24  ('', '24', '', '', '', '', '', '', '')
              24.000  24  ('', '24', '', '', '', '', '', '', '')
               00024  24  ('', '24', '', '', '', '', '', '', '')
              00024.  24  ('', '24', '', '', '', '', '', '', '')
           00024.000  24  ('', '24', '', '', '', '', '', '', '')

string: '  8zoom8.  8.000  0008  0008. and0008.000  '
                   8  8  ('', '8', '', '', '', '', '', '', '')
                  8.  8  ('', '8', '', '', '', '', '', '', '')
               8.000  8  ('', '8', '', '', '', '', '', '', '')
                0008  8  ('', '8', '', '', '', '', '', '', '')
               0008.  8  ('', '8', '', '', '', '', '', '', '')
            0008.000  8  ('', '8', '', '', '', '', '', '', '')

string: '  0   00000M0. = 000.  0.0  0.000    000.0   000.000   .000000   .0   '
                   0  0  ('', '0', '', '', '', '', '', '', '')
               00000  0  ('', '0', '', '', '', '', '', '', '')
                  0.  0  ('', '0', '', '', '', '', '', '', '')
                000.  0  ('', '0', '', '', '', '', '', '', '')
                 0.0  0  ('', '', '0', '', '', '', '', '', '')
               0.000  0  ('', '', '0', '', '', '', '', '', '')
               000.0  0  ('', '', '0', '', '', '', '', '', '')
             000.000  0  ('', '', '0', '', '', '', '', '', '')
             .000000  0  ('', '', '0', '', '', '', '', '', '')
                  .0  0  ('', '', '0', '', '', '', '', '', '')

string: '  .0000023456    .0000023456000     .0005872    .0005872000   .00503   .00503000   '
         .0000023456  0.0000023456  ('', '', '', '.0000023456', '', '', '', '', '')
      .0000023456000  0.0000023456  ('', '', '', '.0000023456', '', '', '', '', '')
            .0005872  0.0005872  ('', '', '', '.0005872', '', '', '', '', '')
         .0005872000  0.0005872  ('', '', '', '.0005872', '', '', '', '', '')
              .00503  0.00503  ('', '', '', '.00503', '', '', '', '', '')
           .00503000  0.00503  ('', '', '', '.00503', '', '', '', '', '')

string: '  .068    .0680000   .8   .8000  .123456123456    .123456123456000    '
                .068  0.068  ('', '', '', '.068', '', '', '', '', '')
            .0680000  0.068  ('', '', '', '.068', '', '', '', '', '')
                  .8  0.8  ('', '', '', '.8', '', '', '', '', '')
               .8000  0.8  ('', '', '', '.8', '', '', '', '', '')
       .123456123456  0.123456123456  ('', '', '', '.123456123456', '', '', '', '', '')
    .123456123456000  0.123456123456  ('', '', '', '.123456123456', '', '', '', '', '')

string: '  .657   .657000   .45    .4500000   .7    .70000  0.0000023230000   000.0000023230000   '
                .657  0.657  ('', '', '', '.657', '', '', '', '', '')
             .657000  0.657  ('', '', '', '.657', '', '', '', '', '')
                 .45  0.45  ('', '', '', '.45', '', '', '', '', '')
            .4500000  0.45  ('', '', '', '.45', '', '', '', '', '')
                  .7  0.7  ('', '', '', '.7', '', '', '', '', '')
              .70000  0.7  ('', '', '', '.7', '', '', '', '', '')
     0.0000023230000  0.000002323  ('', '', '', '.000002323', '', '', '', '', '')
   000.0000023230000  0.000002323  ('', '', '', '.000002323', '', '', '', '', '')

string: '  0.0081000    0000.0081000  0.059000   0000.059000     '
           0.0081000  0.0081  ('', '', '', '.0081', '', '', '', '', '')
        0000.0081000  0.0081  ('', '', '', '.0081', '', '', '', '', '')
            0.059000  0.059  ('', '', '', '.059', '', '', '', '', '')
         0000.059000  0.059  ('', '', '', '.059', '', '', '', '', '')

string: '  0.78987400000 snow  00000.78987400000  0.4400000   00000.4400000   '
       0.78987400000  0.789874  ('', '', '', '.789874', '', '', '', '', '')
   00000.78987400000  0.789874  ('', '', '', '.789874', '', '', '', '', '')
           0.4400000  0.44  ('', '', '', '.44', '', '', '', '', '')
       00000.4400000  0.44  ('', '', '', '.44', '', '', '', '', '')

string: '  -0.5000  -0000.5000   0.90   000.90   0.7   000.7   '
             -0.5000  -0.5  ('-', '', '', '.5', '', '', '', '', '')
          -0000.5000  -0.5  ('-', '', '', '.5', '', '', '', '', '')
                0.90  0.9  ('', '', '', '.9', '', '', '', '', '')
              000.90  0.9  ('', '', '', '.9', '', '', '', '', '')
                 0.7  0.7  ('', '', '', '.7', '', '', '', '', '')
               000.7  0.7  ('', '', '', '.7', '', '', '', '', '')

string: '  2.6    00002.6   00002.60000  4.71   0004.71    0004.7100   '
                 2.6  2.6  ('', '', '', '', '2.6', '', '', '', '')
             00002.6  2.6  ('', '', '', '', '2.6', '', '', '', '')
         00002.60000  2.6  ('', '', '', '', '2.6', '', '', '', '')
                4.71  4.71  ('', '', '', '', '4.71', '', '', '', '')
             0004.71  4.71  ('', '', '', '', '4.71', '', '', '', '')
           0004.7100  4.71  ('', '', '', '', '4.71', '', '', '', '')

string: '  23.49   00023.49   00023.490000  103.45   0000103.45   0000103.45000    '
               23.49  23.49  ('', '', '', '', '23.49', '', '', '', '')
            00023.49  23.49  ('', '', '', '', '23.49', '', '', '', '')
        00023.490000  23.49  ('', '', '', '', '23.49', '', '', '', '')
              103.45  103.45  ('', '', '', '', '103.45', '', '', '', '')
          0000103.45  103.45  ('', '', '', '', '103.45', '', '', '', '')
       0000103.45000  103.45  ('', '', '', '', '103.45', '', '', '', '')

string: '  10003.45067   000010003.45067   000010003.4506700 '
         10003.45067  10003.45067  ('', '', '', '', '10003.45067', '', '', '', '')
     000010003.45067  10003.45067  ('', '', '', '', '10003.45067', '', '', '', '')
   000010003.4506700  10003.45067  ('', '', '', '', '10003.45067', '', '', '', '')

string: '  +15000.0012   +000015000.0012   +000015000.0012000    '
         +15000.0012  +15000.0012  ('+', '', '', '', '15000.0012', '', '', '', '')
     +000015000.0012  +15000.0012  ('+', '', '', '', '15000.0012', '', '', '', '')
  +000015000.0012000  +15000.0012  ('+', '', '', '', '15000.0012', '', '', '', '')

string: '  78000.89   000078000.89   000078000.89000    '
            78000.89  78000.89  ('', '', '', '', '78000.89', '', '', '', '')
        000078000.89  78000.89  ('', '', '', '', '78000.89', '', '', '', '')
     000078000.89000  78000.89  ('', '', '', '', '78000.89', '', '', '', '')

string: '  .0457e10   .0457000e10   00000.0457000e10  '
            .0457e10  0.0457e10  ('', '', '', '.0457', '', 'e', '10', '', '')
         .0457000e10  0.0457e10  ('', '', '', '.0457', '', 'e', '10', '', '')
    00000.0457000e10  0.0457e10  ('', '', '', '.0457', '', 'e', '10', '', '')

string: '   258e8   2580000e4   0000000002580000e4   '
               258e8  258e8  ('', '258', '', '', '', 'e', '8', '', '')
           2580000e4  2580000e4  ('', '2580000', '', '', '', 'e', '4', '', '')
  0000000002580000e4  2580000e4  ('', '2580000', '', '', '', 'e', '4', '', '')

string: '  0.782e10   0000.782e10   0000.7820000e10  '
            0.782e10  0.782e10  ('', '', '', '.782', '', 'e', '10', '', '')
         0000.782e10  0.782e10  ('', '', '', '.782', '', 'e', '10', '', '')
     0000.7820000e10  0.782e10  ('', '', '', '.782', '', 'e', '10', '', '')

string: '  1.23E2   0001.23E2  0001.2300000E2   '
              1.23E2  1.23E2  ('', '', '', '', '1.23', 'E', '2', '', '')
           0001.23E2  1.23E2  ('', '', '', '', '1.23', 'E', '2', '', '')
      0001.2300000E2  1.23E2  ('', '', '', '', '1.23', 'E', '2', '', '')

string: '  432e-102  0000432e-102   004320000e-106   '
            432e-102  432e-102  ('', '432', '', '', '', 'e-', '102', '', '')
        0000432e-102  432e-102  ('', '432', '', '', '', 'e-', '102', '', '')
      004320000e-106  4320000e-106  ('', '4320000', '', '', '', 'e-', '106', '', '')

string: '  1.46e10and0001.46e10  0001.4600000e10   '
             1.46e10  1.46e10  ('', '', '', '', '1.46', 'e', '10', '', '')
          0001.46e10  1.46e10  ('', '', '', '', '1.46', 'e', '10', '', '')
     0001.4600000e10  1.46e10  ('', '', '', '', '1.46', 'e', '10', '', '')

string: '  1.077e-300  0001.077e-300  0001.077000e-300   '
          1.077e-300  1.077e-300  ('', '', '', '', '1.077', 'e-', '300', '', '')
       0001.077e-300  1.077e-300  ('', '', '', '', '1.077', 'e-', '300', '', '')
    0001.077000e-300  1.077e-300  ('', '', '', '', '1.077', 'e-', '300', '', '')

string: '  1.069e10   0001.069e10   0001.069000e10   '
            1.069e10  1.069e10  ('', '', '', '', '1.069', 'e', '10', '', '')
         0001.069e10  1.069e10  ('', '', '', '', '1.069', 'e', '10', '', '')
      0001.069000e10  1.069e10  ('', '', '', '', '1.069', 'e', '10', '', '')

string: '  105040.03e10  000105040.03e10  105040.0300e10    '
        105040.03e10  105040.03e10  ('', '', '', '', '105040.03', 'e', '10', '', '')
     000105040.03e10  105040.03e10  ('', '', '', '', '105040.03', 'e', '10', '', '')
      105040.0300e10  105040.03e10  ('', '', '', '', '105040.03', 'e', '10', '', '')

string: '  +286E000024.487900  -78.4500e.14500   .0140E789.  '
  +286E000024.487900  +286E24.4879  ('+', '286', '', '', '', 'E', '', '', '24.4879')
     -78.4500e.14500  -78.45e0.145  ('-', '', '', '', '78.45', 'e', '', '.145', '')
          .0140E789.  0.014E789  ('', '', '', '.014', '', 'E', '789', '', '')

string: '  081,12.40E07,95.0120     0045,78,123.03500e-0.00  '
081,12.40E07,95.0120  81,12.4E7,95.012  ('', '', '', '', '81,12.4', 'E', '', '', '7,95.012')
   0045,78,123.03500  45,78,123.035  ('', '', '', '', '45,78,123.035', '', '', '', '')

string: '  0096,78,473.0380e-0.    0008,78,373.066000E0.    0004512300.E0000  '
    0096,78,473.0380  96,78,473.038  ('', '', '', '', '96,78,473.038', '', '', '', '')
  0008,78,373.066000  8,78,373.066  ('', '', '', '', '8,78,373.066', '', '', '', '')
         0004512300.  4512300  ('', '4512300', '', '', '', '', '', '', '')

string: '  ..18000  25..00 36...77   2..8  '
           No match,  No catched string,  No groups.

string: '  3.8..9    .12500.     12.51.400  '
           No match,  No catched string,  No groups.

string: '  00099,111.8713000   -0012,45,83,987.26+0.000,099,88,44.or00,00,00.00must'
   00099,111.8713000  99,111.8713  ('', '', '', '', '99,111.8713', '', '', '', '')
  -0012,45,83,987.26  -12,45,83,987.26  ('-', '', '', '', '12,45,83,987.26', '', '', '', '')
         00,00,00.00  0  ('', '', '0', '', '', '', '', '', '')

string: '  00099,44,and   0000,099,88,44.bom'
           00099,44,  99,44  ('', '99,44', '', '', '', '', '', '', '')
     0000,099,88,44.  99,88,44  ('', '99,88,44', '', '', '', '', '', '', '')

string: '00,000,00.587000  77,98,23,45.,  this,that '
    00,000,00.587000  0.587  ('', '', '', '.587', '', '', '', '', '')
        77,98,23,45.  77,98,23,45  ('', '77,98,23,45', '', '', '', '', '', '', '')

string: '  ,111  145.20  +9,9,9  0012800  .,,.  1  100,000 '
                ,111  111  ('', '111', '', '', '', '', '', '', '')
              145.20  145.2  ('', '', '', '', '145.2', '', '', '', '')
              +9,9,9  +9,9,9  ('+', '9,9,9', '', '', '', '', '', '', '')
             0012800  12800  ('', '12800', '', '', '', '', '', '', '')
                   1  1  ('', '1', '', '', '', '', '', '', '')
             100,000  100,000  ('', '100,000', '', '', '', '', '', '', '')

string: '1,1,1.111  000,001.111   -999.  0.  111.110000  1.1.1.111  9.909,888'
           1,1,1.111  1,1,1.111  ('', '', '', '', '1,1,1.111', '', '', '', '')
         000,001.111  1.111  ('', '', '', '', '1.111', '', '', '', '')
               -999.  -999  ('-', '999', '', '', '', '', '', '', '')
                  0.  0  ('', '0', '', '', '', '', '', '', '')
          111.110000  111.11  ('', '', '', '', '111.11', '', '', '', '')

3voto

entonio Points 1286

En prenant une certaine liberté avec les exigences, vous recherchez

\d+([\d,]?\d)*(\.\d+)?

Mais remarquez que cela correspondra, par exemple, à 11,11,1.

0 votes

Par curiosité, y a-t-il une raison pour laquelle vous avez opté pour \d+([\d,]?\d)*(\.\d+)? au lieu de \d+(,\d+)*(\.\d+)? ? Je pense qu'ils donneraient des matches équivalents, même si les groupes de capture seraient différents.

0 votes

Il n'y a pas de raison particulière, c'est le résultat de l'utilisation d'une expression plus complexe pour ne pas faire correspondre des formats invalides.

1voto

David Alexander Points 11

Voici une autre construction qui commence par le format de nombre le plus simple, puis, sans se chevaucher, ajoute progressivement des formats de nombre plus complexes :

Java regep :

(\d)|([1-9]\d+)|(\.\d+)|(\d\.\d*)|([1-9]\d+\.\d*)|([1-9]\d{0,2}(,\d{3})+(\.\d*)?)

En tant que chaîne Java (notez le \N supplémentaire nécessaire pour échapper à \N et . puisque \N et . ont une signification spéciale dans une regexp lorsqu'ils sont seuls) :

String myregexp="(\\d)|([1-9]\\d+)|(\\.\\d+)|(\\d\\.\\d*)|([1-9]\\d+\\.\\d*)|([1-9]\\d{0,2}(,\\d{3})+(\\.\\d*)?)";   

Explication :

  1. Cette regexp a la forme A|B|C|D|E|F où A,B,C,D,E,F sont elles-mêmes des regexps qui ne se chevauchent pas. En général, je trouve plus facile de commencer par les correspondances les plus simples possibles, A. Si A ne correspond pas à ce que vous voulez, créez alors un B qui est une modification mineure de A et qui inclut un peu plus de ce que vous voulez. Puis, sur la base de B, créez un C qui en attrape davantage, etc. Je trouve aussi qu'il est plus facile de créer des regexps qui ne se chevauchent pas ; il est plus facile de comprendre une regexp avec 20 regexps simples qui ne se chevauchent pas et qui sont reliées par des OR plutôt que quelques regexps avec des correspondances plus complexes. Mais, chacun son truc !

  2. A est ( \d ) et correspond à exactement un des 0,1,2,3,4,5,6,7,8,9, ce qui ne peut pas être plus simple !

  3. B est ([1-9]) \d +) et ne correspond qu'aux numéros à 2 chiffres ou plus, le premier excluant le 0 . B correspond exactement à l'un des 10, 11, 12,... B ne recouvre pas A mais est une petite modification de A.

  4. C est (. \d +) et ne correspond qu'à une décimale suivie d'un ou plusieurs chiffres. C correspond exactement à l'un des éléments suivants : .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .00 .01 .02 ... . .23000 ... C autorise les zéros de queue à droite, ce que je préfère : s'il s'agit de données de mesure, le nombre de zéros de queue indique le niveau de précision. Si vous ne voulez pas des zéros de queue à droite, changez (. \d +) à (. \d *[1-9]) mais cela exclut également .0 qui, je pense, devrait être autorisé. C est aussi une petite modification de A.

  5. D est ( \d.\d *) qui est A plus les décimales avec les zéros de queue à droite. D ne correspond qu'à un seul chiffre, suivi d'une décimale, suivie de zéro ou plusieurs chiffres. D correspond à 0. 0.0 0.1 0.2 ....0.01000...9. 9.0 9.1..0.0230000 .... 9.9999999999... Si vous voulez exclure "0.", changez D en ( \d.\d +). Si vous voulez exclure les zéros de queue à droite, changez D en ( \d.\d *[1-9]) mais cela exclut la version 2.0 qui, selon moi, devrait être incluse. D ne recouvre pas A, B, ou C.

  6. E est ([1-9]) \d +. \d *) qui correspond à B plus les décimales avec les zéros de queue à droite. Si vous voulez exclure "13.", par exemple, changez alors E en ([1-9] \d +. \d +). E ne chevauche pas A, B, C ou D. E correspond à 10. 10.0 10.0100 .... 99.9999999999... Les zéros de fin peuvent être traités comme dans 4. et 5.

  7. F est ([1-9]) \d {0,2}(, \d {3})+(. \d *) ?) et ne correspond qu'aux nombres avec des virgules et éventuellement des décimales permettant des zéros de fin à droite. Le premier groupe ([1-9] \d {0,2}) correspond à un chiffre non nul suivi de zéro, un ou deux chiffres supplémentaires. Le deuxième groupe (, \d {3})+ correspond à un groupe de 4 caractères (une virgule suivie d'exactement trois chiffres) et ce groupe peut correspondre une ou plusieurs fois (pas de correspondance signifie pas de virgule !). Enfin, (. \d *) ? ne correspond à rien, ou correspond à . par lui-même, ou correspond à un . décimal suivi d'un nombre quelconque de chiffres, voire aucun. Encore une fois, pour exclure des choses comme "1 111.", changez (. \d *) à (. \d +). Les zéros de fin de ligne peuvent être traités comme dans 4. ou 5. F ne chevauche pas A,B,C,D, ou E. Je n'ai pas trouvé de regexp plus simple pour F.

Faites-moi savoir si vous êtes intéressé et je peux modifier ce qui précède pour gérer les zéros de queue à droite comme vous le souhaitez.

Voici ce qui correspond au regexp et ce qui ne correspond pas :

0
1
02 <- invalid
20
22
003 <- invalid
030 <- invalid
300
033 <- invalid
303
330
333
0004 <- invalid
0040 <- invalid
0400 <- invalid
4000
0044 <- invalid
0404 <- invalid
0440 <- invalid
4004
4040
4400
0444 <- invalid
4044
4404
4440
4444
00005 <- invalid
00050 <- invalid
00500 <- invalid
05000 <- invalid
50000
00055 <- invalid
00505 <- invalid
00550 <- invalid
05050 <- invalid
05500 <- invalid
50500
55000
00555 <- invalid
05055 <- invalid
05505 <- invalid
05550 <- invalid
50550
55050
55500
. <- invalid
.. <- invalid
.0
0.
.1
1.
.00
0.0
00. <- invalid
.02
0.2
02. <- invalid
.20
2.0
20.
.22
2.2
22.
.000
0.00
00.0 <- invalid
000. <- invalid
.003
0.03
00.3 <- invalid
003. <- invalid
.030
0.30
03.0 <- invalid
030. <- invalid
.033
0.33
03.3 <- invalid
033. <- invalid
.303
3.03
30.3
303.
.333
3.33
33.3
333.
.0000
0.000
00.00 <- invalid
000.0 <- invalid
0000. <- invalid
.0004
0.0004
00.04 <- invalid
000.4 <- invalid
0004. <- invalid
.0044
0.044
00.44 <- invalid
004.4 <- invalid
0044. <- invalid
.0404
0.404
04.04 <- invalid
040.4 <- invalid
0404. <- invalid
.0444
0.444
04.44 <- invalid
044.4 <- invalid
0444. <- invalid
.4444
4.444
44.44
444.4
4444.
.00000
0.0000
00.000 <- invalid
000.00 <- invalid
0000.0 <- invalid
00000. <- invalid
.00005
0.0005
00.005 <- invalid
000.05 <- invalid
0000.5 <- invalid
00005. <- invalid
.00055
0.0055
00.055 <- invalid
000.55 <- invalid
0005.5 <- invalid
00055. <- invalid
.00505
0.0505
00.505 <- invalid
005.05 <- invalid
0050.5 <- invalid
00505. <- invalid
.00550
0.0550
00.550 <- invalid
005.50 <- invalid
0055.0 <- invalid
00550. <- invalid
.05050
0.5050
05.050 <- invalid
050.50 <- invalid
0505.0 <- invalid
05050. <- invalid
.05500
0.5500
05.500 <- invalid
055.00 <- invalid
0550.0 <- invalid
05500. <- invalid
.50500
5.0500
50.500
505.00
5050.0
50500.
.55000
5.5000
55.000
550.00
5500.0
55000.
.00555
0.0555
00.555 <- invalid
005.55 <- invalid
0055.5 <- invalid
00555. <- invalid
.05055
0.5055
05.055 <- invalid
050.55 <- invalid
0505.5 <- invalid
05055. <- invalid
.05505
0.5505
05.505 <- invalid
055.05 <- invalid
0550.5 <- invalid
05505. <- invalid
.05550
0.5550
05.550 <- invalid
055.50 <- invalid
0555.0 <- invalid
05550. <- invalid
.50550
5.0550
50.550
505.50
5055.0
50550.
.55050
5.5050
55.050
550.50
5505.0
55050.
.55500
5.5500
55.500
555.00
5550.0
55500.
.05555
0.5555
05.555 <- invalid
055.55 <- invalid
0555.5 <- invalid
05555. <- invalid
.50555
5.0555
50.555
505.55
5055.5
50555.
.55055
5.5055
55.055
550.55
5505.5
55055.
.55505
5.5505
55.505
555.05
5550.5
55505.
.55550
5.5550
55.550
555.50
5555.0
55550.
.55555
5.5555
55.555
555.55
5555.5
55555.
, <- invalid
,, <- invalid
1, <- invalid
,1 <- invalid
22, <- invalid
2,2 <- invalid
,22 <- invalid
2,2, <- invalid
2,2, <- invalid
,22, <- invalid
333, <- invalid
33,3 <- invalid
3,33 <- invalid
,333 <- invalid
3,33, <- invalid
3,3,3 <- invalid
3,,33 <- invalid
,,333 <- invalid
4444, <- invalid
444,4 <- invalid
44,44 <- invalid
4,444
,4444 <- invalid
55555, <- invalid
5555,5 <- invalid
555,55 <- invalid
55,555
5,5555 <- invalid
,55555 <- invalid
666666, <- invalid
66666,6 <- invalid
6666,66 <- invalid
666,666
66,6666 <- invalid
6,66666 <- invalid
66,66,66 <- invalid
6,66,666 <- invalid
,666,666 <- invalid
1,111.
1,111.11
1,111.110
01,111.110 <- invalid
0,111.100 <- invalid
11,11. <- invalid
1,111,.11 <- invalid
1111.1,10 <- invalid
01111.11,0 <- invalid
0111.100, <- invalid
1,111,111.
1,111,111.11
1,111,111.110
01,111,111.110 <- invalid
0,111,111.100 <- invalid
1,111,111.
1,1111,11.11 <- invalid
11,111,11.110 <- invalid
01,11,1111.110 <- invalid
0,111111.100 <- invalid
0002,22.2230 <- invalid
.,5.,., <- invalid
2.0,345,345 <- invalid
2.334.456 <- invalid

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X