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

split : différence Python/Perl

11 views
Skip to first unread message

YBM

unread,
Feb 13, 2012, 8:50:37 AM2/13/12
to
Je n'arrive pas à m'expliquer la différence de comportement
de split entre Perl et Python :

>>> print re.split(r'','abcd')
['abcd']

Tandis que :

$ perl -e '$,=","; print split(m{},"abcd"); print "\n"'
a,b,c,d

C'est le comportement de Perl qui me semble correct (entre deux
caractères d'une chaîne, ce qui les sépare c'est "rien").

Bug du module re ?



Damien Wyart

unread,
Feb 13, 2012, 9:18:22 AM2/13/12
to
* YBM <ybm...@nooos.fr.invalid> in fr.comp.lang.python:
C'est plus compliqué que ça. En résumé, il y a des discussions assez
régulières là-dessus depuis 2004, qui stagnent pendant assez longtemps.
Vers 2008, Van Rossum a tranché pour ne pas modifier le comportement
actuel, puis as donné son accord pour éventuellement avoir le "bon"
comportement avec un flag dédié. Mais il ne s'est rien passé... En tous
cas, la doc actuelle pour 2.7 et 3.2 indique : "Note that split will
never split a string on an empty pattern match."

Par la suite, ce sujet a été regroupé dans celui, plus vaste, de
refondre le moteur d'expressions régulières de Python. Un nouveau moteur
va être proposé dans Python 3.3 (à côté du moteur actuel), et ce nouveau
moteur permet bien d'appeler split avec des patterns vides. Ouf !

Voici des liens pour plus de détails :

http://mail.python.org/pipermail/python-dev/2004-August/047272.html
http://mail.python.org/pipermail/patches/2006-January/018705.html

http://bugs.python.org/issue988761
http://bugs.python.org/issue852532
http://bugs.python.org/issue3262
http://bugs.python.org/issue2636
http://pypi.python.org/pypi/regex

--
DW

Alain Ketterlin

unread,
Feb 13, 2012, 9:24:51 AM2/13/12
to
C'est une décision explicite : la doc dit "Note that split will never
split a string on an empty pattern match." Cela recouvre ton exemple,
mais aussi celui de la doc (re.split('x*', 'foo') renvoie 'foo'). Je
suis assez d'accord avec ce choix : par exemple, que devrait faire
re.split('x*','aaaxxxbbb') ? Si le but est de découper en caractères, il
y a mieux que les expressions régulières.

-- Alain.

YBM

unread,
Feb 13, 2012, 9:32:15 AM2/13/12
to

Merci des infos, je ne suis pas le seul à le considérer comme un bug...


Damien Wyart

unread,
Feb 13, 2012, 9:34:38 AM2/13/12
to
* Alain Ketterlin <al...@dpt-info.u-strasbg.fr> in fr.comp.lang.python:
> Si le but est de découper en caractères,
> il y a mieux que les expressions régulières.

Les maximes rimées de fclp ? ;-)

--
DW

YBM

unread,
Feb 13, 2012, 9:35:11 AM2/13/12
to
Le 13.02.2012 15:24, Alain Ketterlin a écrit :
> YBM<ybm...@nooos.fr.invalid> writes:
>
>> Je n'arrive pas à m'expliquer la différence de comportement
>> de split entre Perl et Python :
>>
>>>>> print re.split(r'','abcd')
>> ['abcd']
>>
>> Tandis que :
>>
>> $ perl -e '$,=","; print split(m{},"abcd"); print "\n"'
>> a,b,c,d
>>
>> C'est le comportement de Perl qui me semble correct (entre deux
>> caractères d'une chaîne, ce qui les sépare c'est "rien").
>
> C'est une décision explicite : la doc dit "Note that split will never
> split a string on an empty pattern match." Cela recouvre ton exemple,
> mais aussi celui de la doc (re.split('x*', 'foo') renvoie 'foo'). Je
> suis assez d'accord avec ce choix : par exemple, que devrait faire
> re.split('x*','aaaxxxbbb') ?

[a,b,c,d,e,f]

et avec x+
[aaa,bbb]

> Si le but est de découper en caractères, il
> y a mieux que les expressions régulières.

Pas toujours...



Damien Wyart

unread,
Feb 13, 2012, 9:47:33 AM2/13/12
to
* Alain Ketterlin <al...@dpt-info.u-strasbg.fr> in fr.comp.lang.python:
> C'est une décision explicite : la doc dit "Note that split will never
> split a string on an empty pattern match." Cela recouvre ton exemple,
> mais aussi celui de la doc (re.split('x*', 'foo') renvoie 'foo'). Je
> suis assez d'accord avec ce choix : par exemple, que devrait faire
> re.split('x*','aaaxxxbbb') ?

Pour information, avec le module regex donc je parle dans ma réponse
principale, on obtient ceci :

>>> regex.split('x*','aaaxxxbbb')
['aaa', 'bbb']

--
DW

Damien Wyart

unread,
Feb 13, 2012, 9:54:01 AM2/13/12
to
> > C'est une décision explicite : la doc dit "Note that split will never
> > split a string on an empty pattern match." Cela recouvre ton exemple,
> > mais aussi celui de la doc (re.split('x*', 'foo') renvoie 'foo'). Je
> > suis assez d'accord avec ce choix : par exemple, que devrait faire
> > re.split('x*','aaaxxxbbb') ?

* YBM <ybm...@nooos.fr.invalid> in fr.comp.lang.python:
> [a,b,c,d,e,f]

Faute de frappe ? Je suppose que tu as voulu écrire :
['a', 'a', 'a', 'x', 'x', 'x', 'b', 'b', 'b']
?

Comme indiqué dans un autre message, ce n'est pas ce qui a été retenu
dans le nouveau module d'expressions régulières qui sera intégré
à Python 3.3 (mais peut aussi être compilé manuellement pour 2.7 et
3.2).
--
DW

YBM

unread,
Feb 13, 2012, 10:12:14 AM2/13/12
to
Le 13.02.2012 15:54, Damien Wyart a écrit :
>>> C'est une décision explicite : la doc dit "Note that split will never
>>> split a string on an empty pattern match." Cela recouvre ton exemple,
>>> mais aussi celui de la doc (re.split('x*', 'foo') renvoie 'foo'). Je
>>> suis assez d'accord avec ce choix : par exemple, que devrait faire
>>> re.split('x*','aaaxxxbbb') ?
>
> * YBM<ybm...@nooos.fr.invalid> in fr.comp.lang.python:
>> [a,b,c,d,e,f]
>
> Faute de frappe ? Je suppose que tu as voulu écrire :
> ['a', 'a', 'a', 'x', 'x', 'x', 'b', 'b', 'b']
> ?

Non, je persiste :

$ perl -e '$,=","; print split(m{x*},"abxxxcdefxxx"); print "\n"'
a,b,c,d,e,f

> Comme indiqué dans un autre message, ce n'est pas ce qui a été retenu
> dans le nouveau module d'expressions régulières qui sera intégré
> à Python 3.3 (mais peut aussi être compilé manuellement pour 2.7 et
> 3.2).

c'est bien dommage, ce n'est pas logique... * est gourmand.




Damien Wyart

unread,
Feb 13, 2012, 10:29:42 AM2/13/12
to
> > > > C'est une décision explicite : la doc dit "Note that split will never
> > > > split a string on an empty pattern match." Cela recouvre ton exemple,
> > > > mais aussi celui de la doc (re.split('x*', 'foo') renvoie 'foo'). Je
> > > > suis assez d'accord avec ce choix : par exemple, que devrait faire
> > > > re.split('x*','aaaxxxbbb') ?

> > > [a,b,c,d,e,f]

> > Faute de frappe ? Je suppose que tu as voulu écrire :
> > ['a', 'a', 'a', 'x', 'x', 'x', 'b', 'b', 'b']
> > ?

* YBM <ybm...@nooos.fr.invalid> in fr.comp.lang.python:
> Non, je persiste :

> $ perl -e '$,=","; print split(m{x*},"abxxxcdefxxx"); print "\n"'
> a,b,c,d,e,f

Du coup tu ne répondais pas à Alain alors que tu plaçait ta réponse
juste après sa question. C'est un peu déroutant...
--
DW

YBM

unread,
Feb 13, 2012, 10:35:25 AM2/13/12
to
Euh... je me suis emmêlé les pinceaux avec mes différents tests et
différent terminaux...

Ceci dit je voulais dire que, selon moi, ceci est logique :

['a','a','a','b','b','b'] pour re.split('x*','aaaxxxbbb')





Alain Ketterlin

unread,
Feb 13, 2012, 10:56:06 AM2/13/12
to
Euh, avec re aussi (en 2.6 au moins). Je serais plus surpris d'obtenir
['a','a','a','b','b','b'] (mais c'est sûrement parce que je fuis perl
comme la peste).

Si le choix change avec 3+ (si j'ai bien compris), il faudra s'y faire.
Après tout, c'est une question de convention, puisque
['a','aa','bb','b'] serait tout aussi correct, bien qu'improbable (et
inconsistant).

-- Alain.

Damien Wyart

unread,
Feb 13, 2012, 11:02:41 AM2/13/12
to
> > Pour information, avec le module regex donc je parle dans ma réponse
> > principale, on obtient ceci :

> >>>> regex.split('x*','aaaxxxbbb')
> > ['aaa', 'bbb']

* Alain Ketterlin <al...@dpt-info.u-strasbg.fr> in fr.comp.lang.python:
> Euh, avec re aussi (en 2.6 au moins). Je serais plus surpris d'obtenir
> ['a','a','a','b','b','b'] (mais c'est sûrement parce que je fuis perl
> comme la peste).

Désolé, j'ai testé trop vite, j'ai oublié de désactiver le mode
"compatibilité avec re" (et on retrouvait bien ce que donne le module re
en 2.6). Du coup, en mode non-compatible, on obtient ceci, et c'est donc
bien cette nouveauté que je voulais citer au départ :

>>> regex.split('x*','aaaxxxbbb',flags=regex.V1)
['', 'a', 'a', 'a', 'b', 'b', 'b', '']

> Si le choix change avec 3+ (si j'ai bien compris), il faudra s'y faire.
> Après tout, c'est une question de convention, puisque
> ['a','aa','bb','b'] serait tout aussi correct, bien qu'improbable (et
> inconsistant).

A priori le choix semble assez cohérent avec ce que souhaitait
intuitivement YBM : le pattern est vide là où ça ne matche pas et
gourmand là où ça matche.

--
DW

YBM

unread,
Feb 13, 2012, 11:09:16 AM2/13/12
to
Le 13.02.2012 17:02, Damien Wyart a écrit :
...
>>>> regex.split('x*','aaaxxxbbb',flags=regex.V1)
> ['', 'a', 'a', 'a', 'b', 'b', 'b', '']
>
>> Si le choix change avec 3+ (si j'ai bien compris), il faudra s'y faire.
>> Après tout, c'est une question de convention, puisque
>> ['a','aa','bb','b'] serait tout aussi correct, bien qu'improbable (et
>> inconsistant).
>
> A priori le choix semble assez cohérent avec ce que souhaitait
> intuitivement YBM : le pattern est vide là où ça ne matche pas et
> gourmand là où ça matche.

Sauf que les '' en premier et en dernier, ça fait un peu désordre là...


0 new messages