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

Propriétés Unicode dans les regex Python

2 views
Skip to first unread message

Olivier Miakinen

unread,
Nov 5, 2022, 1:53:29 PM11/5/22
to
[diapublication avec f.c.l.regexp, suivi vers f.c.l.python]

Bonjour,


Je viens de me rendre compte que dans Python 3.8.10 les propriétés Unicode
\p{xx} et \P{xx} ne sont pas supportées dans les regex :

<https://www.pcre.org/original/doc/html/pcresyntax.html#SEC4>
<https://www.pcre.org/original/doc/html/pcresyntax.html#SEC5>


J'obtiens :
File "/usr/lib/python3.8/sre_parse.py", line 426, in _escape
raise source.error("bad escape %s" % escape, len(escape))
re.error: bad escape \p at position 0


Est-ce que quelqu'un sait si c'est supporté dans une autre version de
Python, ou s'il est prévu que ça le soit un jour ?


Cordialement,
--
Olivier Miakinen

Alain Ketterlin

unread,
Nov 6, 2022, 4:24:33 AM11/6/22
to
Olivier Miakinen <om+...@miakinen.net> writes:

> Je viens de me rendre compte que dans Python 3.8.10 les propriétés Unicode
> \p{xx} et \P{xx} ne sont pas supportées dans les regex :
>
> <https://www.pcre.org/original/doc/html/pcresyntax.html#SEC4>
> <https://www.pcre.org/original/doc/html/pcresyntax.html#SEC5>
>
>
> J'obtiens :
> File "/usr/lib/python3.8/sre_parse.py", line 426, in _escape
> raise source.error("bad escape %s" % escape, len(escape))
> re.error: bad escape \p at position 0

Oui, re ne fournit qu'une partie des "escapes" de pcre (il manque aussi
\h et \v et d'autres).

> Est-ce que quelqu'un sait si c'est supporté dans une autre version de
> Python, ou s'il est prévu que ça le soit un jour ?

Je ne sais pas, mais je sais qu'une bibliothèque du niveau de PCRE est
un très gros boulot, et pas forcément une priorité pour Python
j'imagine.

Cela étant, la doc mentionne une bibliothèque "regex", qui apparemment a
bonne réputation. Je n'en sais pas plus.

https://docs.python.org/3/library/re.html ("See also" à la fin de l'intro)

https://stackoverflow.com/questions/7063420/perl-compatible-regular-expression-pcre-in-python

(Le second lien est une réponse ancienne, mais qui me semble bien
informée.)

-- Alain.

Olivier Miakinen

unread,
Nov 6, 2022, 1:46:39 PM11/6/22
to
Le 06/11/2022 10:24, Alain Ketterlin m'a répondu :
>
>> [...]
>
>> Est-ce que quelqu'un sait si c'est supporté dans une autre version de
>> Python, ou s'il est prévu que ça le soit un jour ?
>
> Je ne sais pas, mais je sais qu'une bibliothèque du niveau de PCRE est
> un très gros boulot, et pas forcément une priorité pour Python
> j'imagine.

Je m'étais imaginé que python pouvait réutiliser la bibliothèque PCRE
(ou PCRE2) existant sur <http://pcre.org/>, mais cela pose peut-être
des problèmes que je ne soupçonne pas forcément (droits ? existence
sur toutes les plateformes ? etc.)

> Cela étant, la doc mentionne une bibliothèque "regex", qui apparemment a
> bonne réputation. Je n'en sais pas plus.
>
> https://docs.python.org/3/library/re.html ("See also" à la fin de l'intro)
>
> https://stackoverflow.com/questions/7063420/perl-compatible-regular-expression-pcre-in-python
>
> (Le second lien est une réponse ancienne, mais qui me semble bien
> informée.)

Oui, tout cela est très prometteur. Un grand merci pour ta réponse.

--
Olivier Miakinen

ast

unread,
Nov 6, 2022, 2:29:09 PM11/6/22
to
Semble fonctionner avec le module regex qui est bien plus complet que re

pip install regex


>>> regex.search(r"\p{Lu}", "abcdEfgh")
<regex.Match object; span=(4, 5), match='E'>


Dominique

unread,
Nov 9, 2022, 4:52:30 AM11/9/22
to
Le 09/11/2022 à 09:33, Stefan Ram a écrit :

> import unicodedata
>
> source = "abcdEfgh"
> for i, ch in enumerate( source ):
> if unicodedata.category( ch )== 'Lu':
> print( i, ch )
>
>

Bonjour,

Pourrais-tu expliquer ton script que je ne comprends pas ? À quoi
correspond 'Lu' ? Est-ce spécifique unicodedata ?

Je te remercie,

--
Dominique
Courriel : dominique point sextant ate orange en France
Esto quod es

Olivier Miakinen

unread,
Nov 9, 2022, 5:44:10 AM11/9/22
to
Le 09/11/2022 09:33, Stefan Ram a écrit :
>
> Si l'installation de modules supplémentaires n'est
> pas envisageable, il existe aussi une possibilité
> avec l'installation habituelle de Python sans modules
> supplémentaires, mais pas avec les expressions
> régulières seules.
>
> import unicodedata
>
> source = "abcdEfgh"
> for i, ch in enumerate( source ):
> if unicodedata.category( ch )== 'Lu':
> print( i, ch )
>

Très intéressant ! Merci pour cela.
<https://docs.python.org/fr/3/library/unicodedata.html>

--
Olivier Miakinen

Alain Ketterlin

unread,
Nov 9, 2022, 8:13:41 AM11/9/22
to
D'après https://www.compart.com/en/unicode/category/Lu il y a 1791
caractères Unicode dans la catégorie Lu. Donc si tu veux construire une
expression régulière re en remplaçant "\p{Lu}" par "[.....]" dans une
expression régulière pcre, tu vas aboutir à une expression énorme...

Mais effectivement, si tu n'as pas vraiment besoin d'une expression
régulière et que le test de correspondance peut être fait "à la main",
c'est une solution.

-- Alain.

Dominique

unread,
Nov 9, 2022, 8:46:19 AM11/9/22
to
Le 09/11/2022 à 11:09, Stefan Ram a écrit :
> Dominique <z...@aol.com> writes:
>> Le 09/11/2022 à 09:33, Stefan Ram a écrit :
>>> import unicodedata
>>> source = "abcdEfgh"
>>> for i, ch in enumerate( source ):
>>> if unicodedata.category( ch )== 'Lu':
>>> print( i, ch )
>> Bonjour,
>
> Bonjour !
>
>> Pourrais-tu expliquer ton script que je ne comprends pas ? À quoi
>> correspond 'Lu' ? Est-ce spécifique unicodedata ?
>
> Il s'agit d'une catégorie de caractère spécifique à Unicode,
> qui est attribuée à chaque caractère par l'annexe #44 "Base
> de données des caractères Unicode" de la spécification Unicode.
> "L" = lettre, "u" = "upper case" (majuscule).
>
>

Ah d'accord, merci. Je ne connaissais pas. J'aurai appris quelque chose
aujourd'hui :)

Bon après-midi à toi,

Olivier Miakinen

unread,
Nov 9, 2022, 9:12:34 AM11/9/22
to
Le 09/11/2022 à 14:13, Alain Ketterlin m'a répondu :
>
> D'après https://www.compart.com/en/unicode/category/Lu il y a 1791
> caractères Unicode dans la catégorie Lu. Donc si tu veux construire une
> expression régulière re en remplaçant "\p{Lu}" par "[.....]" dans une
> expression régulière pcre, tu vas aboutir à une expression énorme...

Certes ! :-)

Sans compter que cette collection peut augmenter au fil des différentes
versions d'Unicode.

> Mais effectivement, si tu n'as pas vraiment besoin d'une expression
> régulière et que le test de correspondance peut être fait "à la main",
> c'est une solution.

Je posais la question pour un outil dans lequel tout se fait par
expressions régulières. Par conséquent le module unicodedata ne peut
pas me servir directement pour cela, mais il pourrait m'être utile
dans d'autres circonstances et je remercie encore Stefan de me l'avoir
fait découvrir.

Pour l'heure je vais me contenter des [A-Z] ou [a-z], quitte à y
ajouter des caractères accentués au cas par cas.

Cordialement,

--
Olivier Miakinen

Olivier Miakinen

unread,
Nov 9, 2022, 9:21:59 AM11/9/22
to
Le 09/11/2022 à 14:34, Stefan Ram a écrit :
>
> for i in range( 1114112 ): # Python 3.9

Je ne comprends pas le commentaire. Cette syntaxe ne fonctionnerait pas
pour les versions de Python inférieures à 3.9 ?

--
Olivier Miakinen

Olivier Miakinen

unread,
Nov 9, 2022, 11:07:30 AM11/9/22
to
Le 09/11/2022 à 15:41, Stefan Ram a écrit :
>
>>>for i in range( 1114112 ): # Python 3.9
>>Je ne comprends pas le commentaire. Cette syntaxe ne fonctionnerait pas
>>pour les versions de Python inférieures à 3.9 ?
>
> Je pensais que d'autres versions de Python pourraient
> supporter d'autres versions d'Unicode avec plus ou moins
> de points de code. Par conséquent, le numéro "1114112"
> pourrait devoir être modifié.

Je comprends mieux.

Mais du coup tu peux supprimer ce commentaire, car Unicode garantit
qu'il n'existera jamais de point de code au delà de U+10FFFF, en
décimal 1114111. On n'aurait pas eu cette limitation en UTF-8, qui
permettait au départ des points de code jusqu'à U+7FFFFFFF (en 6
octets), mais la limitation vient d'UTF-16.

On peut noter que cette limitation d'UTF-16, qui impose à Unicode
la limitation à U+10FFFF, limite du même coup UTF-8 : on n'aura
jamais en UTF-8 d'encodage nécessitant plus de 4 octets.


--
Olivier Miakinen

Alain Ketterlin

unread,
Nov 9, 2022, 1:46:34 PM11/9/22
to
Olivier Miakinen <om+...@miakinen.net> writes:

> Le 09/11/2022 à 14:13, Alain Ketterlin m'a répondu :
>>
>> D'après https://www.compart.com/en/unicode/category/Lu il y a 1791
>> caractères Unicode dans la catégorie Lu. Donc si tu veux construire une
>> expression régulière re en remplaçant "\p{Lu}" par "[.....]" dans une
>> expression régulière pcre, tu vas aboutir à une expression énorme...
[...]
>> Mais effectivement, si tu n'as pas vraiment besoin d'une expression
>> régulière et que le test de correspondance peut être fait "à la main",
>> c'est une solution.
>
> Je posais la question pour un outil dans lequel tout se fait par
> expressions régulières. Par conséquent le module unicodedata ne peut
> pas me servir directement pour cela, mais il pourrait m'être utile
> dans d'autres circonstances et je remercie encore Stefan de me l'avoir
> fait découvrir.
>
> Pour l'heure je vais me contenter des [A-Z] ou [a-z], quitte à y
> ajouter des caractères accentués au cas par cas.

Absolument !

Ma "proposition" était ironique, en fait, j'aurais dû être plus clair.
La catégorie "Lu" inclut, par exemple, les majuscules grecques et
cyrilliques et cherokee et ..., des symboles d'unités (Kelvin, Ångström,
Ohm), les ensembles mathématiques classiques (N/Z/Q/R/... avec double
barre), etc.

(Au passage, je ne sais pas très bien pourquoi unicodedata ne donne pas
accès au script d'un caractère... ce qui pourrait aussi être utile ici
pour faire un peu le tri dans Lu.)

-- Alain.

Alain Ketterlin

unread,
Nov 9, 2022, 1:47:04 PM11/9/22
to
Olivier Miakinen <om+...@miakinen.net> writes:

> [...] Unicode garantit qu'il n'existera jamais de point de code au
> delà de U+10FFFF, en décimal 1114111. [...]

Fun fact : sys.maxunicode conserve cette valeur (c'est juste pour info,
ce n'est pas forcément utile comme tu le fais remarquer dans le reste de
ton message).

-- Alain.

Olivier Miakinen

unread,
Nov 9, 2022, 1:52:40 PM11/9/22
to
Le 09/11/2022 à 19:46, Alain Ketterlin a écrit :
>
>> [...] Unicode garantit qu'il n'existera jamais de point de code au
>> delà de U+10FFFF, en décimal 1114111. [...]
>
> Fun fact : sys.maxunicode conserve cette valeur (c'est juste pour info,
> ce n'est pas forcément utile comme tu le fais remarquer dans le reste de
> ton message).

Variable ou pas, range(sys.maxunicode + 1) sera quand même plus lisible,
ou en tout cas plus informatif, que range(1114112). Alors l'info est
bonne à prendre, merci.


--
Olivier Miakinen

Olivier Miakinen

unread,
Nov 9, 2022, 2:09:04 PM11/9/22
to
Le 09/11/2022 à 19:42, Alain Ketterlin a écrit :
>
> (Au passage, je ne sais pas très bien pourquoi unicodedata ne donne pas
> accès au script d'un caractère... ce qui pourrait aussi être utile ici
> pour faire un peu le tri dans Lu.)

Oui, je suis absolument d'accord.


--
Olivier Miakinen

ast

unread,
Nov 10, 2022, 8:29:21 AM11/10/22
to
Le 09/11/2022 à 14:34, Stefan Ram a écrit :
> Alain Ketterlin <al...@universite-de-strasbourg.fr.invalid> writes:
>> D'après https://www.compart.com/en/unicode/category/Lu il y a 1791
>> caractères Unicode dans la catégorie Lu. Donc si tu veux construire une
>> expression régulière re en remplaçant "\p{Lu}" par "[.....]" dans une
>> expression régulière pcre, tu vas aboutir à une expression énorme...
>
> Bonne idée !
>
> main.py
>
> import re
> import unicodedata
>
> Lu = "["
> for i in range( 1114112 ): # Python 3.9
> ch = chr( i )
> if unicodedata.category( ch )== "Lu":
> Lu += ch
> Lu += "]"
>
> print( len( Lu ))
> print( re.search( Lu, "abcdEfgh" ))
>
> sortie :
>
> 1790
> <re.Match object; span=(4, 5), match='E'>
>
>

Amusant.

Pourquoi mets-tu "python 3.9" en commentaire ?
Il y a quelque chose dans ce programme qui ne passe pas avec les
versions antérieures ?

ast

unread,
Nov 10, 2022, 8:32:08 AM11/10/22
to
Le 09/11/2022 à 15:41, Stefan Ram a écrit :
> Je pensais que d'autres versions de Python pourraient
> supporter d'autres versions d'Unicode avec plus ou moins
> de points de code. Par conséquent, le numéro "1114112"
> pourrait devoir être modifié.
>
>
Ah ! la réponse à ma question
0 new messages