Google Groups no longer supports new Usenet posts or subscriptions. Historical content remains viewable.
Dismiss

Expression rationnelle

4 views
Skip to first unread message

Stéphane Santon

unread,
May 11, 2013, 5:56:34 PM5/11/13
to
Bonjour,

Pour le calcul d'une url, je dᅵsire filtrer les petits mots de mon
choix dans une chaine :
- placᅵs en dᅵbut de chaine et suivis d'un tiret,
- placᅵs en fin de chaine et prᅵcᅵdᅵs d'un tiret,
- placᅵs dans la chaine et entourᅵs d'un tiret.

Voici ce que je fais et qui fonctionne.

$lsMasque = array(
'(^au-|^de-|^du-|^des-|^en-|^l-|^le-|^la-|^les-)',
'(-au-|-de-|-du-|-des-|-en-|-l-|-le-|-la-|-les-)',
'(-au$|-de$|-du$|-des$|-en$|-l$|-le$|-la$|-les$)'
);
$lsUrl = preg_replace( $lsMasque, array('','-',''), $lsUrl);

Mais y aurait-il plus simple ?

Merci

--
Stᅵphane

Jeune Chambre Economique de Saintes *** http://www.jce-saintes.org
Agitateurs d'idᅵes... accᅵlᅵrateurs de talents !

BTS Electrotechnique *** http://enselec.santonum.eu


denisb

unread,
May 12, 2013, 12:26:35 PM5/12/13
to
Le 11/05/13 23:56, Stéphane Santon a écrit :
> Mais y aurait-il plus simple ?


$lsUrl =
trim(preg_replace("#(?:^|-)((?:a|d)u|des?|en|l(?:es?|a)?)(?:-|$)#", "-",
$lsUrl), "-");


--
@@@@@
E -00 comme on est very beaux dis !
’ `) /
|\_ ==”

Stéphane Santon

unread,
May 12, 2013, 12:53:23 PM5/12/13
to
Bonjour,

denisb a ᅵcrit :
> $lsUrl = trim(preg_replace("#(?:^|-)((?:a|d)u|des?|en|l(?:es?|a)?)(?:-|$)#",
> "-", $lsUrl), "-");

Gloups.... va falloir que j'approfondisse les rᅵgles pour comprendre
comment ᅵa marche et l'intᅵgrer...

En tout cas Merci ! :-D

denisb

unread,
May 12, 2013, 1:29:56 PM5/12/13
to
Le 12/05/13 18:53, Stéphane Santon a écrit :
> comment ça marche


ne nous préoccupons pas des ?:
on a donc : (^|-)((a|d)u|des?|en|l(es?|a)?)(-|$)

(^|-) => un '-' ou bien le début
( => [suivi de]
(a|d)u => 'a' ou 'd' suivi de 'u' ('au' ou 'du')
| => [ou bien]
des? => 'de' seul ou pouvant être suivi de 's' ('de' ou 'des')
| => [ou bien]
en => 'en' ('en')
| => [ou bien]
l(es?|a)? => 'l' seul ou pouvant être suivi soit de 'e' pouvant être suivi
de 's', soit de 'a' ('l' ou 'le' ou 'les' ou 'la')
) => [suivi de]
(-|$) => un '-' ou bien la fin


toutes les occurrences de ton tableau étant donc remplacées par '-'
on trim pour supprimer les '-' de début et de fin (au cas où il
y en ait).

Stéphane Santon

unread,
May 13, 2013, 2:33:24 AM5/13/13
to
Bonjour,

Merci de ces explications.

Mais la question que je me posais surtout est :
quelle partie de syntaxe permet de ne pas supprimer le 'de' de dᅵbut et
le 'les' de fin dans 'dechets-recyclables' ?

denisb a ᅵcrit :
> Le 12/05/13 18:53, Stᅵphane Santon a ᅵcrit :
>> comment ᅵa marche
>
>
> ne nous prᅵoccupons pas des ?:
> on a donc : (^|-)((a|d)u|des?|en|l(es?|a)?)(-|$)
>
> (^|-) => un '-' ou bien le dᅵbut
> ( => [suivi de]
> (a|d)u => 'a' ou 'd' suivi de 'u' ('au' ou 'du')
> | => [ou bien]
> des? => 'de' seul ou pouvant ᅵtre suivi de 's' ('de' ou 'des')
> | => [ou bien]
> en => 'en' ('en')
> | => [ou bien]
> l(es?|a)? => 'l' seul ou pouvant ᅵtre suivi soit de 'e' pouvant ᅵtre suivi
> de 's', soit de 'a' ('l' ou 'le' ou 'les' ou 'la')
> ) => [suivi de]
> (-|$) => un '-' ou bien la fin
>
>
> toutes les occurrences de ton tableau ᅵtant donc remplacᅵes par '-'
> on trim pour supprimer les '-' de dᅵbut et de fin (au cas oᅵ il
> y en ait).

--

Stéphane Santon

unread,
May 13, 2013, 2:37:43 AM5/13/13
to
Stᅵphane Santon a ᅵcrit :
> Mais la question que je me posais surtout est :
> quelle partie de syntaxe permet de ne pas supprimer le 'de' de dᅵbut et le
> 'les' de fin dans 'dechets-recyclables' ?

Ah si si... c'est bon j'ai compris.
S'il y a un dᅵbut avant le petit mot, il /faut/ qu'il soit suivi par un
tiret (ou la fin). Donc OK. :-)

Pierre Maurette

unread,
May 13, 2013, 3:32:28 AM5/13/13
to
Stᅵphane Santon :
> Bonjour,
>
> Pour le calcul d'une url, je dᅵsire filtrer les petits mots de mon choix dans
> une chaine :
> - placᅵs en dᅵbut de chaine et suivis d'un tiret,
> - placᅵs en fin de chaine et prᅵcᅵdᅵs d'un tiret,
> - placᅵs dans la chaine et entourᅵs d'un tiret.
>
> Voici ce que je fais et qui fonctionne.
>
> $lsMasque = array(
> '(^au-|^de-|^du-|^des-|^en-|^l-|^le-|^la-|^les-)',
> '(-au-|-de-|-du-|-des-|-en-|-l-|-le-|-la-|-les-)',
> '(-au$|-de$|-du$|-des$|-en$|-l$|-le$|-la$|-les$)'
> );
> $lsUrl = preg_replace( $lsMasque, array('','-',''), $lsUrl);
>
> Mais y aurait-il plus simple ?

Je pratique peu les expressions rationnelles, et surtout pas en Php.
C'est d'ailleurs parce que je le regrette que je lis les messages de ce
groupe, en tant qu'exercice ;-)

Votre code me semble lisible, et maintenable, c'est liᅵ. On imagine
qu'il est sans doute factorisable un chouᅵa. Je saurais faire un truc
en Python, en Php, en me contentant de bricoler sur du texte, on peut
peut-ᅵtre envisager un truc comme:

$petitsmots = array(
'au', 'de', 'du', 'des', 'en', 'l', 'le', 'la', 'les'
);
$petitsmots = implode('|', $petitsmots);
$lsMasque = array(
'(^('.$petitsmots.')-)',
'(-('.$petitsmots.')-)',
'(-('.$petitsmots.')$)'
);

--
Pierre Maurette


Olivier Miakinen

unread,
May 13, 2013, 4:27:42 AM5/13/13
to
Bonjour,

Le 12/05/2013 18:26, denisb r�pondait � St�phane Santon :
>
> $lsUrl =
> trim(preg_replace("#(?:^|-)((?:a|d)u|des?|en|l(?:es?|a)?)(?:-|$)#", "-",
> $lsUrl), "-");

Parfois on complique en voulant simplifier... Je conserve ton id�e du
trim suivant un remplacement par "-" dans tous les cas, id�e que je
trouve bonne. Mais il me semble que conserver la liste de petits mots
telle quelle est plus simple que de factoriser ... et tout aussi court :

$lsUrl =
trim(preg_replace("#(?:^|-)(au|de|du|des|en|l|le|la|les)(?:-|$)#", "-",
$lsUrl), "-");

Par ailleurs, je profite de ma r�ponse pour rappeler qu'il existe un
groupe fr.comp.lang.regexp consacr� aux expressions rationnelles. Ce
n'�tait pas forc�ment le plus adapt� ici puisque la r�ponse comprend
un changement du code PHP, mais cela pourrait servir dans d'autres
occasions.

Cordialement,
--
Olivier Miakinen

Olivier Miakinen

unread,
May 13, 2013, 4:36:51 AM5/13/13
to
Le 13/05/2013 09:32, Pierre Maurette a �crit :
>
> [...] en Php, en me contentant de bricoler sur du texte, on peut
> peut-�tre envisager un truc comme:
>
> $petitsmots = array(
> 'au', 'de', 'du', 'des', 'en', 'l', 'le', 'la', 'les'
> );
> $petitsmots = implode('|', $petitsmots);
> $lsMasque = array(
> '(^('.$petitsmots.')-)',
> '(-('.$petitsmots.')-)',
> '(-('.$petitsmots.')$)'
> );

Oui, c'est aussi une bonne solution.

Encore plus simple :

$petitsmots = "(au|de|du|des|en|l|le|la|les)";
$lsMasque = array(
'^'.$petitsmots.'-',
'-'.$petitsmots.'-',
'-'.$petitsmots.'$'
);

Voire, si l'on est au clair avec la syntaxe des noms de variables et de
l'interpr�tation entre guillemets doubles :

$lsMasque = array(
"^$petitsmots-",
"-$petitsmots-",
"-$petitsmots$"
);

Olivier Miakinen

unread,
May 13, 2013, 10:15:26 AM5/13/13
to
Le 13/05/2013 10:27, je rᅵpondais ᅵ denisb :
>
> [...] Je conserve ton idᅵe du trim suivant un remplacement par "-"
> dans tous les cas, idᅵe que je trouve bonne.

Mᅵme si cela allait sans dire, ᅵa va toujours mieux en le disant.
Le code de denisb fait la mᅵme chose que celui de Stᅵphane Santon ᅵ
trois conditions : la premiᅵre condition est que la chaᅵne de dᅵpart
ne comporte pas de "-" au dᅵbut ou ᅵ la fin ; la seconde condition
est que la chaᅵne de dᅵpart ne soit pas rᅵduite ᅵ l'un des petits
mots ; la troisiᅵme condition est que la chaᅵne ne commence ni ne
finisse par *deux* petits mots.

Ainsi, sur les chaᅵnes suivantes, le rᅵsultat ne devrait pas ᅵtre le
mᅵme entre les deux scripts :
"-une-chaine-qui-commence-par-un-tiret"
"une-chaine-qui-finit-par-un-tiret-"
"-une-chaine-qui-commence-et-finit-par-un-tiret-"
"au"
"des-l-aube-a-l-heure-ou-blanchit-la-campagne"
"bouge-bouge-bouge-de-la"

Par ailleurs, bien que le rᅵsultat soit le mᅵme entre les deux scripts,
je ne suis pas sᅵr qu'il soit celui souhaitᅵ par Stᅵphane lorsque deux
petits mots se suivent ᅵ l'intᅵrieur d'une chaᅵne :
"le-village-au-fond-de-la-vallee"
-> "village-fond-la-vallee" et pas "village-fond-vallee"

Cordialement,
--
Olivier Miakinen

Pierre Maurette

unread,
May 13, 2013, 11:37:49 AM5/13/13
to
Olivier Miakinen :

[...]

> Par ailleurs, bien que le rᅵsultat soit le mᅵme entre les deux scripts,
> je ne suis pas sᅵr qu'il soit celui souhaitᅵ par Stᅵphane lorsque deux
> petits mots se suivent ᅵ l'intᅵrieur d'une chaᅵne :
> "le-village-au-fond-de-la-vallee"
> -> "village-fond-la-vallee" et pas "village-fond-vallee"

Pour ce cas, il me semble qu'une rustine serait d'appliquer le
preg_replace() plusieurs fois. Tant que "ᅵa matche".
Ce matin j'avais vu le truc et fait le test sur implode('-',
$petitsmots).

--
Pierre Maurette


Olivier Miakinen

unread,
May 13, 2013, 12:16:36 PM5/13/13
to
Le 13/05/2013 17:37, Pierre Maurette m'a rᅵpondu :
>
>> Par ailleurs, bien que le rᅵsultat soit le mᅵme entre les deux scripts,
>> je ne suis pas sᅵr qu'il soit celui souhaitᅵ par Stᅵphane lorsque deux
>> petits mots se suivent ᅵ l'intᅵrieur d'une chaᅵne :
>> "le-village-au-fond-de-la-vallee"
>> -> "village-fond-la-vallee" et pas "village-fond-vallee"
>
> Pour ce cas, il me semble qu'une rustine serait d'appliquer le
> preg_replace() plusieurs fois. Tant que "ᅵa matche".

Oui. Une mᅵthode plus directe, mais plus difficile ᅵ lire pour qui
maᅵtrise mal les regexp, serait d'utiliser les assertions.

Pierre Maurette

unread,
May 13, 2013, 1:40:02 PM5/13/13
to
Olivier Miakinen :
La rustine que je proposais - mᅵme pas vraiment d'ailleurs - est en
fait assez poreuse, et mᅵme toute pourrite. Elle dᅵbouche sur du non
maintenable puisque basᅵe sur le fait que '-blah-' est remplacᅵ par '-'
et rien d'autre. Il ne semble pas aberrant de dᅵcider un jour de
remplacer par '', '_', '.', etc. Il vaut mieux faire du propre tout de
suite que plus tard dans l'urgence.

--
Pierre Maurette


Olivier Miakinen

unread,
May 14, 2013, 12:53:58 PM5/14/13
to
Le 13/05/2013 19:40, Pierre Maurette m'a rᅵpondu :
>>
>> Oui. Une mᅵthode plus directe, mais plus difficile ᅵ lire pour qui
>> maᅵtrise mal les regexp, serait d'utiliser les assertions.
>
> [...] Il vaut mieux faire du propre tout de suite que plus tard dans
> l'urgence.

D'accord. Alors voici ce que je propose.

$lsMasque = array(
'/(^|-)(au|de|du|des|en|l|le|la|les)(?=-|$)/',
'/^-/'
);
$lsUrl = preg_replace($lsMasque, '', $lsUrl);

Avec l'hypothᅵse qu'il n'y a jamais de trait d'union ᅵ conserver
en dᅵbut de chaᅵne, ᅵa devrait fonctionner.
0 new messages