Expresión regular para hacer coincidir números con o sin comas y decimales en el texto

96

Estoy tratando de ubicar y reemplazar todos los números en un cuerpo de texto. Encontré algunos ejemplos de expresiones regulares, que casi resuelven el problema, pero ninguno es perfecto todavía. El problema que tengo es que los números de mi texto pueden tener o no decimales y comas. Por ejemplo:

"El zorro de 5000 libras saltó una valla de 99,999.99998713 pies".

La expresión regular debería devolver " 5000" y " 99,999.99998713". Ejemplos He encontrado que los números de la coma están divididos o están limitados a dos lugares decimales. Estoy empezando a comprender las expresiones regulares lo suficiente como para ver por qué algunos ejemplos están limitados a dos lugares decimales, pero aún no he aprendido cómo superarlo y también incluir la coma para obtener la secuencia completa.

Aquí está mi última versión:

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

Que devuelve, " 5000", " 99,99", " 9.99" y " 998713" para el texto anterior.

Rosquilla
fuente
1
¿Qué lenguaje de programación o sabor de expresiones regulares?
Matt Ball
7
Parece que casi todas las respuestas aquí cometen el error de permitir cosas como .,.,.o 9,9,9,9o 9,9.99.9. Estas expresiones regulares no requerirán que los números estén en el formato adecuado y, en el peor de los casos, tratarán la puntuación como números. Hay algunos ajustes opcionales posibles (por ejemplo, si permitir ceros iniciales y finales), pero algunas de las respuestas que estoy viendo son totalmente incorrectas. Realmente no me gusta votar negativamente, especialmente en los intentos honestos, pero siento que las respuestas aquí necesitan una limpieza. Esta es una pregunta común y definitivamente se volverá a hacer.
Justin Morgan
En caso de que no lo sepa, eche un vistazo a regexpal.com
entonio
Perdón por la demora Matt. Estoy usando ActionScript 3 de Adobe. Pensé que el comportamiento de las expresiones regulares era el mismo que el de JavaScript, pero probé la sugerencia de Justin en regexpal.com y la comparé con los resultados de mi aplicación Flash y vi dos resultados diferentes, ambos incorrectos.
Debería funcionar esta vez, según mis propias pruebas. Avísame si aún necesita refinamiento.
Justin Morgan

Respuestas:

288

EDITAR: Dado que esto ha obtenido muchas visitas, permítanme comenzar dándoles a todos lo que buscaron en 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])?$

Ahora que eso está fuera del camino, la mayor parte de lo siguiente es un comentario sobre lo compleja que puede llegar a ser la expresión regular si intenta ser inteligente con ella, y por qué debería buscar alternativas. Lea bajo su propio riesgo.


Esta es una tarea muy común, pero todas las respuestas que veo aquí hasta ahora aceptará entradas que no coinciden con el formato de número, como por ejemplo ,111, 9,9,9o incluso .,,.. Eso es bastante simple de solucionar, incluso si los números están incrustados en otro texto. En mi humilde opinión cualquier cosa que no puede cargar 1,234.56 y 1234- y sólo esos números salida privado de abc22 1,234.56 9.9.9.9 def 1234una respuesta incorrecta.

En primer lugar, si no necesita hacer todo esto en una expresión regular, no lo haga. Una sola expresión regular para dos formatos de números diferentes es difícil de mantener incluso cuando no están incrustados en otro texto. Lo que realmente debe hacer es dividir todo en espacios en blanco, luego ejecutar dos o tres expresiones regulares más pequeñas en los resultados. Si esa no es una opción para ti, sigue leyendo.

Patrón básico

Teniendo en cuenta los ejemplos que ha dado, aquí hay una expresión regular simple que permite prácticamente cualquier 0000formato entero o decimal y bloquea todo lo demás:

^\d*\.?\d+$

Aquí hay uno que requiere 0,000formato:

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

Ponlos juntos y las comas se vuelven opcionales siempre que sean consistentes:

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

Números incrustados

Los patrones anteriores requieren que toda la entrada sea un número. Está buscando números incrustados en el texto, por lo que debe aflojar esa parte. Por otro lado, no quiere que vea catch22y crea que ha encontrado el número 22. Si está usando algo con soporte de búsqueda hacia atrás (como .NET), esto es bastante fácil: reemplace ^con (?<!\S)y $con (?!\S)y estará bien ir:

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

Si está trabajando con JavaScript o Ruby o algo así, las cosas comienzan a parecer más complejas:

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

Tendrás que usar grupos de captura; No puedo pensar en una alternativa sin el apoyo de mirar atrás. Los números que desea estarán en el Grupo 1 (asumiendo que todo el partido es el Grupo 0).

Validación y reglas más complejas

Creo que eso cubre tu pregunta, así que si eso es todo lo que necesitas, deja de leer ahora. Si quieres ser más elegante, las cosas se vuelven muy complejas muy rápidamente. Dependiendo de su situación, es posible que desee bloquear alguno o todos los siguientes:

  • Entrada vacía
  • Ceros iniciales (por ejemplo, 000123)
  • Ceros finales (por ejemplo, 1.2340000)
  • Decimales que comienzan con el punto decimal (p. Ej., 0,001 en lugar de 0,001)

Solo por el placer de hacerlo, supongamos que desea bloquear los primeros 3, pero permita el último. ¿Qué deberías hacer? Le diré lo que debe hacer, debe usar una expresión regular diferente para cada regla y reducir progresivamente sus coincidencias. Pero por el bien del desafío, así es como lo haces todo en un patrón gigante:

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

Y esto es lo que significa:

(?<!\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.

Probado aquí: http://rextester.com/YPG96786

Esto permitirá cosas como:

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

Bloqueará cosas como:

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

Hay varias formas de hacer esta expresión regular más simple y más corta, pero comprenda que cambiar el patrón aflojará lo que se considera un número.

Dado que muchos motores de expresiones regulares (por ejemplo, JavaScript y Ruby) no admiten la búsqueda hacia atrás negativa, la única forma de hacerlo correctamente es con grupos de captura:

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

Los números que está buscando estarán en el grupo de captura 1.

Probado aquí: http://rubular.com/r/3HCSkndzhT

Una nota final

Obviamente, esta es una expresión regular masiva, complicada y casi ilegible. Disfruté del desafío, pero debería considerar si realmente desea utilizarlo en un entorno de producción. En lugar de intentar hacer todo en un solo paso, puede hacerlo en dos: una expresión regular para detectar cualquier cosa que pueda ser un número, luego otra para eliminar lo que no sea un número. O puede hacer un procesamiento básico y luego usar las funciones de análisis numérico integradas de su idioma. Tu elección.

Justin Morgan
fuente
1
Este es un muy buen intento, pero puede haber un problema: dependiendo de la codicia del motor, un número dado puede coincidir parcialmente con dos de los formatos de la competencia, en lugar de hacer coincidir individualmente el correcto, es decir, 5000 puede producir 500 más 0 Eso me hace un poco escéptico de tratar de cubrir demasiado con una sola expresión, y es por eso que di una respuesta más simple con la advertencia de posibles falsos positivos. Al final del día, el rigor de los requisitos debería dictar la solución.
Entonio
@entonio - Ese es un punto justo. Podría funcionar con la última edición. Por cierto, su voto negativo no fue mío, ya que señaló la posible coincidencia 1,11,11.
Justin Morgan
Estoy usando ActionScript, que creo que se comporta igual que JavaScript. Usando el primer patrón que recomendó, obtengo los siguientes resultados en mi cadena de prueba (para validación, simplemente estoy devolviendo las coincidencias envueltas en "<< [resultado] >>"): El << 5 >> 000 lb. fox saltó una << 9 >> 9 <<, 9 >> <<99>> <<. 9 >> <<99>> <<98>> <<71>> cerca de 3 pies.
2
Bueno, uno de sus votos positivos es mío :) ya que creo que su respuesta es lo más completa posible y se esfuerza. Solo para hacer de esto un comentario de contenido, una nota para el OP, el?: Al comienzo de los grupos está ahí para que no se devuelvan de forma autónoma en el resultado ('capturado'), a pesar de que contribuyen a la coincidencia de toda la expresión; cada número formateado en la entrada coincide con la expresión completa.
entonio
@Michael y @entonio: vea la última edición, que parece funcionar. Este es uno de esos problemas de expresiones regulares que son más difíciles de lo que parecen.
Justin Morgan
10

Hace algunos días, trabajé en el problema de eliminar los ceros finales de la cadena de un número .

En la continuidad de ese problema, encuentro este interesante porque amplía el problema a números que comprenden comas.

Tomé el patrón de expresiones regulares que había escrito en el problema anterior en el que trabajé y lo mejoré para que pueda tratar los números con comas como respuesta a este problema.

Me he dejado llevar por mi entusiasmo y mi gusto por las expresiones regulares. No sé si el resultado se ajusta exactamente a la necesidad expresada por Michael Prescott. Me interesaría conocer los puntos que sobran o faltan en mi expresión regular, y corregirlo para que sea más adecuado para ti.

Ahora, después de una larga sesión de trabajo en esta expresión regular, tengo una especie de peso en el cerebro, así que no estoy lo suficientemente fresco para dar muchas explicaciones. Si los puntos son oscuros, y si alguien puede llegar a estar lo suficientemente interesado, por favor, pregúnteme.

La expresión regular está construida para que pueda detectar los números expresados ​​en notación científica 2E10 o incluso 5,22,454.12E-00.0478 , eliminando ceros innecesarios en las dos partes de dichos números también. Si un exponente es igual a cero, el número se modifica para que no haya más exponente.

Puse alguna verificación en el patrón para que algunos casos particulares no coincidan, por ejemplo, '12 ..57 ' no coincidirá. Pero en ', 111' la cadena '111' coincide porque la coma anterior se considera una coma que no está en un número sino en una coma de oración.

Creo que debería mejorarse la gestión de las comas, porque me parece que solo hay 2 dígitos entre comas en la numeración india. No será difícil de corregir, supongo

A continuación, se muestra un código que demuestra cómo funciona mi expresión regular. Hay dos funciones, según se quiera transformar los números '.1245' en '0.1245' o no. No me sorprendería que en ciertos casos de cadenas de números persistan errores o coincidencias no deseadas o no coincidentes; entonces me gustaría conocer estos casos para comprender y corregir la deficiencia.

Pido disculpas por este código escrito en Python, pero las expresiones regulares son trans-idioma y creo que todos serán capaces de entender el patrón 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

resultado

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', '', '', '', '')
eyquem
fuente
8

La expresión regular a continuación coincidirá con ambos números de su ejemplo.

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

Devolverá 5000 y 99,999.99998713, coincidiendo con sus requisitos.

Leones
fuente
3
Esto coincidirá con la coma en this,that.
Justin Morgan
@Justin Morgan: tienes razón, no probé esa condición. Aquí hay una versión actualizada que funcionará para todos los casos, excepto para un número que comience con una coma o un punto. \b\d[\d,.]+\b
Leons
Mucho mejor, pero aún permitirá 9....9o 1,,,,X(aunque la X no se incluirá en el partido).
Justin Morgan
1
Por cierto, \b\d[\d,.]*\bestá lo suficientemente cerca como para que si editas tu respuesta, eliminaré el -1. Sin embargo, debería ser un * en lugar de un +; \b\d[\d,.]+\bno permitirá números de un solo dígito.
Justin Morgan
@Justin Morgan: gracias por la información. Esta pregunta era definitivamente más compleja de lo que parecía. Actualicé mi respuesta en función de sus comentarios, tiene sentido.
Leons
3

Tomándose una cierta libertad con los requisitos, está buscando

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

Pero tenga en cuenta que esto coincidirá, por ejemplo, con 11,11,1

entonio
fuente
Por curiosidad, ¿hay alguna razón por la que fueras en \d+([\d,]?\d)*(\.\d+)?lugar de \d+(,\d+)*(\.\d+)?? Creo que darían coincidencias equivalentes, aunque los grupos de captura serían diferentes.
Justin Morgan
Hola. Sin ninguna razón especial, fue una resaca de comenzar con una expresión más compleja para no coincidir con formatos no válidos.
entonio
3
\d+(,\d+)*(\.\d+)?

Esto supone que siempre hay al menos un dígito antes o después de cualquier coma o decimal y también supone que hay como máximo un decimal y que todas las comas preceden al decimal.

Neil
fuente
2
Esto no restringe los grupos de comas al formato de 3 dígitos. Aceptará 999999,9,9,9,9.
Justin Morgan
Aunque probablemente debería señalar que esto está más cerca de ser correcto que la mayoría de los demás. Tu -1 no es mía.
Justin Morgan
Este es el RE que usaría, aunque con otro paso de validación después (posiblemente no con un RE); intentar hacer todo con un RE hace la vida mucho más difícil.
Donal Fellows
@Justin Morgan No estaba claro si la coma solo se aceptaba en grupos de 3 dígitos. Pero eso se resuelve fácilmente cambiando (,\d+)a (,\d\d\d), supongo.
Neil
2

Esta expresión regular:

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

Coincidió con todos los números de la cadena:

1 1.0 0.1 1.001 1,000 1,000,000 1000.1 1,000.1 1,323,444,000 1,999 1,222,455,666.0 1,244

Eric D
fuente
2

Aquí hay una expresión regular:

(?:\d+)((\d{1,3})*([\,\ ]\d{3})*)(\.\d+)?

que acepta números:

  • sin espacios y / o decimales, ej. 123456789,123.123
  • con comas o espacios como separador de miles y / o decimales, ej. 123 456 789, 123 456 789.100, 123,456,3,232,300,000.00

Pruebas: http://regexr.com/3h1a2

Kacper Cz
fuente
Esto funciona bien en regexr.com, pero en el módulo python re no funciona
Pardhu
1

Aquí hay otra construcción que comienza con el formato de número más simple y luego, de una manera no superpuesta, agrega progresivamente formatos de número más complejos:

Regep de Java:

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

Como una cadena de Java (tenga en cuenta el \ adicional necesario para escapar a \ y. Desde \ y. Tienen un significado especial en una expresión regular cuando están solos):

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

Explicación:

  1. Esta expresión regular tiene la forma A | B | C | D | E | F donde A, B, C, D, E, F son en sí mismas expresiones regulares que no se superponen. En general, me resulta más fácil comenzar con las coincidencias más simples posibles, A. Si A falla las coincidencias que desea, cree una B que sea una modificación menor de A e incluya un poco más de lo que desea. Luego, basado en B, cree una C que capture más, etc. También me resulta más fácil crear expresiones regulares que no se superponen; Es más fácil entender una expresión regular con 20 expresiones regulares simples no superpuestas conectadas con OR en lugar de unas pocas expresiones regulares con coincidencias más complejas. Pero, ¡cada uno a lo suyo!

  2. A es (\ d) y coincide exactamente con uno de 0,1,2,3,4,5,6,7,8,9 que no puede ser más simple.

  3. B es ([1-9] \ d +) y solo coincide con números con 2 o más dígitos, el primero excluyendo 0. B coincide exactamente con uno de 10,11,12, ... B no se superpone a A, pero es una pequeña modificación de A.

  4. C es (. \ D +) y solo coincide con un decimal seguido de uno o más dígitos. C coincide exactamente con uno de .0 .1 .2 .3 .4 .5 .6 .7 .8 .9 .00 .01 .02 .... .23000 ... C permite arrastrar eros a la derecha, lo que prefiero: si se trata de datos de medición, el número de ceros finales indica el nivel de precisión. Si no quiere los ceros finales a la derecha, cambie (. \ D +) a (. \ D * [1-9]) pero esto también excluye .0 que creo que debería estar permitido. C también es una pequeña modificación de A.

  5. D es (\ d. \ D *) que es A más decimales con ceros a la derecha. D solo coincide con un solo dígito, seguido de un decimal, seguido de cero o más dígitos. D coincide con 0. 0.0 0.1 0.2 .... 0.01000 ... 9. 9.0 9.1..0.0230000 .... 9.9999999999 ... Si desea excluir "0." luego cambie D a (\ d. \ d +). Si desea excluir los ceros finales a la derecha, cambie D a (\ d. \ D * [1-9]) pero esto excluye 2.0, que creo que debería incluirse. D no se superpone a A, B o C.

  6. E es ([1-9] \ d +. \ D *) que es B más decimales con ceros a la derecha. Si desea excluir "13.", por ejemplo, cambie E a ([1-9] \ d +. \ D +). E no se superpone a A, B, C o D. E coincide con 10. 10.0 10.0100 .... 99.9999999999 ... Los ceros finales se pueden manejar como en 4. y 5.

  7. F es ([1-9] \ d {0,2} (, \ d {3}) + (. \ D *)?) Y solo coincide con números con comas y posiblemente decimales, permitiendo ceros finales a la derecha. El primer grupo ([1-9] \ d {0,2}) coincide con un dígito distinto de cero seguido de cero, uno o dos dígitos más. El segundo grupo (, \ d {3}) + coincide con un grupo de 4 caracteres (una coma seguida de exactamente tres dígitos) y este grupo puede coincidir una o más veces (¡sin coincidencias significa que no hay comas!). Finalmente, (. \ D *)? coincide con nada, o coincide. por sí mismo o coincide con un decimal. seguido de cualquier número de dígitos, posiblemente ninguno. Nuevamente, para excluir cosas como "1,111.", Cambie (. \ D *) a (. \ D +). Los ceros finales se pueden manejar como en 4. o 5. F no se superpone a A, B, C, D o E. No podría pensar en una expresión regular más fácil para F.

Avíseme si está interesado y puedo editar arriba para manejar los ceros finales a la derecha como desee.

Esto es lo que coincide con regexp y lo que no:

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
David Alexander
fuente
1
\b\d+,

\ b -------> límite de palabra

\ d + ------> uno o dígito

, --------> que contiene comas,

P.ej:

sddsgg 70.000 sdsfdsf fdgfdg70,00

sfsfsd 5,44,4343 5.7788,44 555

Coincidirá:

70,

5,

44,

, 44

Ibz.Shaikh
fuente
0
(,*[\d]+,*[\d]*)+

Esto coincidiría con cualquier número pequeño o grande como sigue con o sin coma

1
100
1,262
1,56,262
10,78,999
12,34,56,789

o

1
100
1262
156262
1078999
123456789
phpnerd
fuente