[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