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.

Agrupación de regex con el mismo nombre

Estoy tratando de escribir una expresión regular para obtener el nombre de los ingredientes, la cantidad y la unidad de la cadena. La cadena puede tener cualquier patrón como “pohe 2 kg” o “2 Kg pohe” o “2Kg Pohe”.

He intentado con el siguiente código:

<?php
    $units = array("tbsp", "ml", "g", "grams", "kg", "few drops"); // añadir cualquier otra unidad permitida

//patrón mixto
$pattern = '/(?J)(((?<i>^[a-zA-Z\s]+)(?<q>\d*\s*)(?<u>' . join("|", array_map("preg_quote", $units)) . '))|(?<q>^\d*\s*)(?<u>' . join("|", array_map("preg_quote", $units)) . ')(?<i>[a-zA-Z\s]+))/';


$ingredients = '2kg pohe';

preg_match_all($pattern, $ingredients, $m);
print_r($m);
$quantities = $m['q'];
$units = array_map('trim', $m['u']);
$ingrd = array_map('trim', $m['i']);
print_r($quantities);
print_r($units);
print_r($ingrd);
?>

El código anterior funciona para la cadena “2kg pohe”, pero no para “pohe 2kg”.

Si alguien tiene alguna idea de lo que me estoy perdiendo, por favor ayúdeme con esto.

Tags:  , ,

Answer

  1. Avatar for davy.ai

    En el código dado, el patrón regex está diseñado para coincidir con el patrón mixto de la cadena de ingredientes donde la cantidad, unidad y nombre del ingrediente pueden tener cualquier secuencia. Sin embargo, el patrón actual solo coincide con la cantidad y unidad si aparecen antes del nombre del ingrediente. Para que coincida con el patrón donde el nombre del ingrediente viene antes de la cantidad y unidad, es necesario actualizar el patrón.

    Una forma de lograr esto es crear dos patrones separados, uno para el caso en el que la cantidad y unidad aparecen antes del nombre del ingrediente y otro para el caso en que el nombre del ingrediente aparece antes de la cantidad y unidad. Luego, combinar los dos patrones utilizando el operador | para que coincida con cualquier tipo de patrón.

    Aquí está el código actualizado con el patrón regex modificado:

    <?php
    $units = array("tbsp", "ml", "g", "grams", "kg", "few drops"); // agregar cualquier otra unidad permitida
    
    // patrón para cantidad, unidad y luego ingrediente
    $pattern1 = '/(?J)(?P<q>\d*\s*)(?P<u>' . join("|", array_map("preg_quote", $units)) . ')(?P<i>[a-zA-Z\s]+)/';
    
    // patrón para ingrediente, luego cantidad y unidad
    $pattern2 = '/(?J)(?P<i>[a-zA-Z\s]+)(?P<q>\d*\s*)(?P<u>' . join("|", array_map("preg_quote", $units)) . ')/';
    
    $ingredients = 'pohe 2kg';
    
    // coincidir con cualquiera de los patrones
    if(preg_match($pattern1, $ingredients, $m) || preg_match($pattern2, $ingredients, $m)) {
        $quantity = trim($m['q']);
        $unit = trim($m['u']);
        $ingredient = trim($m['i']);
    
        // realizar acciones con los datos extraídos
        echo "Cantidad: $quantity\n";
        echo "Unidad: $unit\n";
        echo "Ingrediente: $ingredient\n";
    } else {
        echo "No se encontró coincidencia";
    }
    ?>
    

    Este código coincidirá con ambos patrones, es decir, cuando la cantidad y unidad están antes o después del nombre del ingrediente.

Comments are closed.