Discussion:
Propriétés Unicode dans les regex Python
(trop ancien pour répondre)
Olivier Miakinen
2022-11-05 17:53:27 UTC
Permalink
[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
2022-11-06 09:24:28 UTC
Permalink
Post by Olivier Miakinen
Je viens de me rendre compte que dans Python 3.8.10 les propriétés Unicode
<https://www.pcre.org/original/doc/html/pcresyntax.html#SEC4>
<https://www.pcre.org/original/doc/html/pcresyntax.html#SEC5>
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).
Post by Olivier Miakinen
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
2022-11-06 18:46:37 UTC
Permalink
Post by Alain Ketterlin
Post by Olivier Miakinen
[...]
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.)
Post by Alain Ketterlin
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
2022-11-06 19:29:07 UTC
Permalink
Post by Olivier Miakinen
[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
<https://www.pcre.org/original/doc/html/pcresyntax.html#SEC4>
<https://www.pcre.org/original/doc/html/pcresyntax.html#SEC5>
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,
Semble fonctionner avec le module regex qui est bien plus complet que re

pip install regex
Post by Olivier Miakinen
regex.search(r"\p{Lu}", "abcdEfgh")
<regex.Match object; span=(4, 5), match='E'>
Stefan Ram
2022-11-09 08:33:13 UTC
Permalink
Post by Olivier Miakinen
[diapublication avec f.c.l.regexp, suivi vers f.c.l.python]
...
Post by Olivier Miakinen
regex.search(r"\p{Lu}", "abcdEfgh")
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 )
Dominique
2022-11-09 09:52:28 UTC
Permalink
Post by Stefan Ram
import unicodedata
source = "abcdEfgh"
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
Stefan Ram
2022-11-09 10:09:10 UTC
Permalink
Post by Olivier Miakinen
Post by Stefan Ram
import unicodedata
source = "abcdEfgh"
print( i, ch )
Bonjour,
Bonjour !
Post by Olivier Miakinen
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).
Dominique
2022-11-09 13:46:17 UTC
Permalink
Post by Stefan Ram
Post by Olivier Miakinen
Post by Stefan Ram
import unicodedata
source = "abcdEfgh"
print( i, ch )
Bonjour,
Bonjour !
Post by Olivier Miakinen
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,
--
Dominique
Courriel : dominique point sextant ate orange en France
Esto quod es
Olivier Miakinen
2022-11-09 10:44:09 UTC
Permalink
Post by Stefan Ram
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"
print( i, ch )
Très intéressant ! Merci pour cela.
<https://docs.python.org/fr/3/library/unicodedata.html>
--
Olivier Miakinen
Alain Ketterlin
2022-11-09 13:13:37 UTC
Permalink
Post by Olivier Miakinen
Post by Stefan Ram
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"
print( i, ch )
Très intéressant ! Merci pour cela.
<https://docs.python.org/fr/3/library/unicodedata.html>
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.
Stefan Ram
2022-11-09 13:34:25 UTC
Permalink
Post by Alain Ketterlin
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'>
Olivier Miakinen
2022-11-09 14:22:00 UTC
Permalink
Post by Stefan Ram
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
Stefan Ram
2022-11-09 14:41:21 UTC
Permalink
Post by Olivier Miakinen
Post by Stefan Ram
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é.
Olivier Miakinen
2022-11-09 16:07:28 UTC
Permalink
Post by Stefan Ram
Post by Olivier Miakinen
Post by Stefan Ram
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
2022-11-09 18:46:58 UTC
Permalink
[...] 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
2022-11-09 18:52:36 UTC
Permalink
Post by Alain Ketterlin
[...] 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
ast
2022-11-10 13:32:06 UTC
Permalink
Post by Stefan Ram
Post by Olivier Miakinen
Post by Stefan Ram
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é.
Ah ! la réponse à ma question

ast
2022-11-10 13:29:18 UTC
Permalink
Post by Stefan Ram
Post by Alain Ketterlin
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 )
Lu += ch
Lu += "]"
print( len( Lu ))
print( re.search( Lu, "abcdEfgh" ))
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 ?
Olivier Miakinen
2022-11-09 14:12:34 UTC
Permalink
Post by Alain Ketterlin
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.
Post by Alain Ketterlin
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
Alain Ketterlin
2022-11-09 18:42:14 UTC
Permalink
Post by Olivier Miakinen
Post by Alain Ketterlin
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...
[...]
Post by Olivier Miakinen
Post by Alain Ketterlin
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.
Olivier Miakinen
2022-11-09 19:09:02 UTC
Permalink
Post by Alain Ketterlin
(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
Continuer la lecture sur narkive:
Loading...