es.davy.ai

Preguntas y respuestas de programación confiables

¿Tienes una pregunta?

Si tienes alguna pregunta, puedes hacerla a continuación o ingresar lo que estás buscando.

¿Cómo extraer todos los valores numéricos de una cadena de texto?

Tengo cadenas que contienen diferentes valores (numéricos y no numéricos mezclados). Quiero poder extraer los valores del texto. No pude entender cómo extraer todos (o la mayoría de) los casos posibles. Tengo una solución parcialmente funcionando como la siguiente:

def extract_values(sentence):
    #sentence = normalizeString(sentence)
    matches = re.findall(r'((\d*\.?\d+(?:\/\d*\.?\d+)?)(?:\s+and\s+(\d*\.?\d+(?:\/\d*\.?\d+)?))?)', sentence)    
    # (\d\sto\s\d\s(and\s\d\/\d)*) << for adding 9 to 11, couldn't fix

    result = []
    for x,y,z in matches:
        if '/' in x:
            result.append(x)
        else:
            result.extend(filter(lambda x: x!="", [y,z]))
    return result

Código del programa principal:

extract_values("Él tiene 1 y 1/2 años. Tiene .5 años y tiene 5 años. Está entre 9 y 11 o entre 9 y 9 y 1/2. Nació el 11/12/20")

Respuesta incorrecta:

['1 y 1/2', '5', '5', '9', '11', '9', '9 y 1/2', '11/12', '20']

Respuesta esperada:

['1 y 1/2', '.5', '5', '9 a 11', '9 a 9 y 1/2', '11/12/20']

Por favor, ten en cuenta la diferencia entre 5 y .5, y entre ‘x a y’ y ‘x a y y z’.

Agradecería cualquier ayuda. Gracias.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    Para extraer todos (o la mayoría) de los posibles casos de valores de una cadena de texto con mezcla de caracteres numéricos y no numéricos, puedes modificar la función extract_values para utilizar una expresión regular más completa y algo de lógica adicional de la siguiente manera:

    import re
    
    def extract_values(sentence):
        # Define la expresión regular para coincidir con valores de diversos formatos
        pattern = r'(?:\b\d+(?:\.\d+)?/\d+\b|\b\d+(?:\.\d+)?\b|\b\.\d+\b|\b\d+(?:\sa\s\d+(?:\sy\s\d+(?:/\d+)?)?)?)'
    
        # Encuentra todas las coincidencias del patrón en la frase
        matches = re.findall(pattern, sentence)
    
        # Elimina duplicados y convierte rangos a la forma 'x a y y z'
        result = []
        for m in matches:
            if 'a' in m:
                parts = m.split('a')
                if 'y' in parts[1]:
                    nums = parts[1].split('y')
                    result.append('{} a {} y {}'.format(parts[0], nums[0], nums[1]))
                else:
                    result.append(m)
            elif '/' in m:
                result.append(m)
            elif m[0] == '.':
                result.append('0{}'.format(m))
            else:
                result.append(m)
    
        return result
    

    Esta función utiliza una expresión regular que coincide con varios formatos de valores, incluyendo enteros, números decimales, fracciones y rangos de números (en forma de x a y o x a y y z). El patrón también utiliza límites de palabra (\b) para asegurar que solo coincida con valores completos, no con parte de palabras o números.

    Luego, la función extrae todas las coincidencias del patrón de expresión regular de la frase de entrada, elimina duplicados y convierte los rangos de números al formato deseado (x a y y z). También agrega un cero inicial a cualquier valor que comience con un punto decimal.

    Ahora, cuando pases la frase de entrada a la función extract_values, deberías obtener la salida esperada:

    print(extract_values("Tiene 1 y 1/2 años. Tiene .5 años y tiene 5 años. Está entre 9 a 11 o 9 a 9 y 1/2. Nació el 11/12/20"))
    # Salida: ['1 y 1/2', '0.5', '5', '9 a 11', '9 a 9 y 1/2', '11/12/20']
    

    Espero que esto sea de ayuda. Déjame saber si tienes alguna pregunta.

Comments are closed.