[Perl] Module pour parser des parenthèses imbriquées

Stéphane Gigandet biz at joueb.com
Lun 18 Déc 14:27:08 CET 2017


Merci beaucoup Laurent!

Regexp::Grammars a l'air très bien, j'ai commencé à jouer avec, mais il 
y a un truc que je n'arrive pas à faire, c'est faire en sorte qu'un 
token matche à minima (de façon "non greedy").

Dans le code ci-dessous, j'aimerais bien que le token [<ingredient>] 
matche "E-300" mais pas "sel - eau" afin que la règle list_ingredients 
fasse la séparation avec le tirets entre espaces. Si je mets - en plus dans
<token: ingredient> [^,;\(\)\[\]\{\}\%]* ça va me couper mon E-300. En 
fait ce que je voudrais faire, c'est mettre un
<token: ingredient> .*? mais ça ne matche plus rien.

use Regexp::Grammars;

my $parser = qr{
<list_ingredients>

<rule: list_ingredients>
     <[composed_ingredient]>* % ([,;]| - )

<token: composed_ingredient> <[ingredient]> <[percent]>? (\( 
<[list_ingredients]> \))? (\[ <[list_ingredients]> \])?

<token: ingredient> [^,;\(\)\[\]\{\}\%]*

<token: percent>(\d+((\.|\,)(\d+))?)\s?\%
};

my  $input = "E-300, sel - eau";

if ($input =~ $parser) {
         use Data::Dumper;
         print STDERR Dumper(\%/);
}

Ca donne ça :

$VAR1 = {
           '' => 'E-300, sel - eau',
           'list_ingredients' => {
                                   '' => 'E-300, sel - eau',
                                   'composed_ingredient' => [
                                                              {
                                                                '' => 
'E-300',
'ingredient' => [
'E-300'
]
                                                              },
                                                              {
                                                                '' => 
'sel - eau',
'ingredient' => [
'sel - eau'
]
                                                              }
                                                            ]
                                 }
         };


Une idée ?

Merci,

Stéphane


> Salut,
>
> Tu peux définir une grammaire complète avec https://metacpan.org/pod/Regexp::Grammars , mais ça demande un investissement non négligeable pour l'apprentissage.
> Sinon s'il ne s'agit que de paires de parenthèses, il y a https://metacpan.org/pod/Regexp::Common::balanced  ou https://metacpan.org/pod/Text::Balanced
>
> Bon travail, Laurent Dami
>
> -----Message d'origine-----
> De : perl-bounces at mongueurs.net [mailto:perl-bounces at mongueurs.net] De la part de Stéphane Gigandet
> Envoyé : lundi 18 décembre 2017 10:41
> À : Liste francophone pour les questions générales sur Perl
> Objet : [Perl] Module pour parser des parenthèses imbriquées
>
> Bonjour,
>
> Pour Open Food Facts j'essaie de parser des listes d'ingrédients qui
> ressemblent à ça :
>
> "farine (12%), chocolat (beurre de cacao (15%), sucre [10%], protéines
> de lait, oeuf 1%) - émulsifiants : E463, E432 et E472 - correcteurs
> d'acidité : E322/E333 E474-E475, acidifiant (acide citrique, acide
> phosphorique) - sel"
>
> Que j'essaie de transformer en arbre comme :
>
> [
>       {ingredient=>'farine', percent => 12},
>       [ingredient=>'chocolat', ingredients => [
>           {ingredient:'beurre de cacao', percent=>15},
>           {ingredient:'sucre', percent=>10},
>           {ingredient:'protéines de lait'},
>           {ingredient:'oeuf', percent=>1},
>       ]},
>       {ingredient=>'émulsifiants', ingredients => [
>           {ingredient=>'E463'},
>           {ingredient=>'E432'},
>           {ingredient=>'E472'},
>       ]},
> ...
>
> Pour l'instant j'ai du code à base de regexp avec une fonction
> récursive, mais c'est très laid et ça marche pas très bien :
> https://github.com/openfoodfacts/openfoodfacts-server/blob/master/lib/ProductOpener/Ingredients.pm#L251
>
> Je suis sûr qu'il y a des modules qui peuvent faire ce genre de trucs
> très bien, vous en connaissez ?
>
> Merci beaucoup,
>
> Stéphane
>
>
>
> _______________________________________________
> Perl mailing list
> Perl at mongueurs.net
> http://listes.mongueurs.net/mailman/listinfo/perl
> _______________________________________________
> Perl mailing list
> Perl at mongueurs.net
> http://listes.mongueurs.net/mailman/listinfo/perl
>



Plus d'informations sur la liste de diffusion Perl