Tengo la siguiente lista en Python:
my_list = ['Prix TTC euros : 10,10', 'Prix HT euros 8,42', 'TVA (20.00%) euros : 1,68']

Quiero obtener todos los números como 10,10, 8,42 y 1,68 sin el número en porcentaje (20.00%)
Mi código:

my_list = ['Prix TTC euros : 10,10', 'Prix HT euros 8,42', 'TVA (20.00%) euros : 1,68']

for item in my_list:
try:
    found = re.search('([+-]?([0-9]*[,.])?[0-9]+)', item).group()
except AttributeError:
    found = None  # apply your error handling
print(found)

Imprime:

10,10
8,42
20.00

Estaba tratando de escapar del último número encontrado 20.00 y obtener 1,68. ¿Hay alguna forma de escapar del número que termina con% o alguna otra solución?

1
Siddiqui Noor 9 may. 2019 a las 21:43

3 respuestas

La mejor respuesta

Hay una manera de evitar hacer coincidir los valores de porcentaje con un límite de palabra seguido de una búsqueda anticipada negativa que rechazará coincidencias seguidas con un símbolo %:

import re

my_list = ['Prix TTC euros : 10,10', 'Prix HT euros 8,42', 'TVA (20.00%) euros : 1,68']

for item in my_list:
    found = re.search(r'[-+]?\b(?!\d+(?:[,.]\d+)?%)\d+(?:[.,]\d+)?', item)
    if found:
        print(found.group())

Consulte la demostración de Python en línea, salida: ['10,10', '8,42', '1,68'].

Consulte también una demostración de expresiones regulares:

  • [-+]?: un - o + opcional
  • \b - un límite de palabra
  • (?!\d+(?:[,.]\d+)?%): una anticipación negativa que falla la coincidencia si hay 1+ dígitos, una secuencia opcional de . o , y luego 1+ dígitos inmediatamente a la derecha de la ubicación actual
  • \d+ - 1+ dígitos
  • (?:[.,]\d+)?: una secuencia opcional de . o , y luego 1+ dígitos.
1
Wiktor Stribiżew 9 may. 2019 a las 19:54

Comencemos con su expresión regular:

found = re.search(r'([+-]?(?:[0-9]*[,.])?[0-9]+)', item).group()

Esto funciona como lo mencionaste. Necesitamos agregar % al final de esta expresión regular como una anticipación negativa

found = re.search(r'([+-]?(?:[0-9]*[,.])?[0-9]+)(?!%)', item).group()

Que imprime:

10,10
8,42
20.0  # <---- note the last digit is missing here

Por lo tanto, para ajustar esta expresión regular más adelante, necesitamos excluir el patrón de números enteros que hemos encontrado (es decir, ([+-]?(?:[0-9]*[,.])?[0-9]+)) SI termina con %.

Así terminamos con:

found = re.search(
    r'([+-]?(?:[0-9]*[,.])?[0-9]+)(?!(?:%|(?:[+-]?(?:[0-9]*[,.])?[0-9]+)))',
    item
).group

Que da lo que queremos:

10,10
8,42
1,68
1
dopstar 9 may. 2019 a las 20:34

En lugar de una anticipación negativa, intente usar una positiva terminando su expresión con (?=[^0-9,.%]|$) - "seguido de algo que no sea %, más partes de un número o nada en absoluto".

Alternativamente, solo extraiga todas las secuencias de [0-9.,%]+ y use Python para tirar las malas coincidencias.

0
Roman Odaisky 9 may. 2019 a las 18:58