Bonjour à tous,

je viens de débuter avec les regexp sous python.

je cherche à matcher des caractères accentués. D'après la doc rien de bien sorcier à condition de compiler ma regexp avec le flag re.LOCALE (si j'ai bien compris à quoi servait ce flag)

Or je n'y suis pas arrivé sans définir explicitement mes caractères sous forme de code point unicode dans ma regex, ce qui finalement annule un peu l'intérêt des regexp...

Voilà mes tests :

Code : Sélectionner tout - Visualiser dans une fenêtre à part
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
 
Python 2.5.2 (r252:60911, Jan  4 2009, 17:40:26)
[GCC 4.3.2] on linux2
Type "help", "copyright", "credits" or "license" for more information.
>>> import re
>>> import locale
>>> locale.getdefaultlocale()
('fr_FR', 'UTF8')
>>> locale.setlocale(locale.LC_ALL,  None)
'C'
>>> locale.setlocale(locale.LC_ALL,  '')
'fr_FR.UTF-8'
>>> locale.setlocale(locale.LC_ALL,  None)
'fr_FR.UTF-8'
>>> pattern = ur'^\w+$'
>>> pattern
u'^\\w+$'
>>> ro = re.compile(pattern, re.LOCALE)
>>> ro
<_sre.SRE_Pattern object at 0xb7df3520>
>>> import sys
>>> print sys.stdin.encoding
UTF-8
>>> # mo : match object
>>> # premier essai avec une byte string
>>> # 'frédéric' : 'fr\xc3\xa9d\xc3\xa9ric'
>>> # je suppose que python encode cette chaîne utf-8
>>> # en unicode pour le moteur de regex
>>> # du coup la séquence de deux héxa \xc3\xa9 devrait être
>>> # vue comme un seul caractère é
>>> # compiler avec le flag re.LOCALE \w devrait matcher
>>> # ce é
>>> mo = ro.match('frédéric')
>>> type(mo)
<type 'NoneType'>
 
>>> # test en enlevant les ancres de ma regexp
>>> pattern = ur'\w+'
>>> ro = re.compile(pattern, re.LOCALE)
>>> mo = ro.match('frédéric')
>>> type(mo)
<type '_sre.SRE_Match'>
>>> mo.string
'fr\xc3\xa9d\xc3\xa9ric'
>>> mo.group(0)
'fr'
>>> mo.groups()
()
>>> mo.start(0)
0
>>> mo.end(0)
2
>>> mo.group(1)
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: no such group
>>> # le moteur de regexp n'a donc pas reconnu le é
>>> # test : en admettant que python fournisse une chaîne type latin1 (donc la séquence utf-8 est vue comme
>>> # deux caractères non acceptables dans un mot)
>>> # il faut convertir la chaîne à tester en chaîne unicode
>>> mo = ro.match(u'frédéric')
>>> type(mo)
<type '_sre.SRE_Match'>
>>> mo.string
u'fr\xe9d\xe9ric'
>>> mo.group(0)
u'fr'
>>> # la seule solution que j'ai trouvé c'est d'insérer des code point unicode dans
>>> # mon pattern
>>> # voir http://www.regular-expressions.info/python.html
>>> pattern = ur'^\w+\u00E9\w+\u00E9\w+$'
>>> ro = re.compile(pattern)
>>> mo = ro.match(u'frédéric')
>>> type(mo)
<type '_sre.SRE_Match'>
>>> mo.string
u'fr\xe9d\xe9ric'
>>> mo.group(0)
u'fr\xe9d\xe9ric'
>>> # ça marche
Est-ce que j'aurais loupé quelque chose ? (en tout cas j'espère)


merci par avance,

Frédéric