Je reçois un message d'erreur lorsque j'utilise cette expression:
re.sub(r"([^\s\w])(\s*\1)+","\\1","...")
J'ai vérifié l'expression régulière à RegExr et il renvoie .
comme prévu. Mais quand je l'essaye dans Python je reçois ce message d'erreur:
raise error, v # invalid expression
sre_constants.error: nothing to repeat
Quelqu'un peut-il expliquer?
Il semble que ce soit un bug python (qui fonctionne parfaitement dans vim). La source du problème est le bit (\ s * ...) +. Fondamentalement, vous ne pouvez pas faire (\s*)+
qui a du sens, car vous essayez de répéter quelque chose qui peut être nul.
>>> re.compile(r"(\s*)+")
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/re.py", line 180, in compile
return _compile(pattern, flags)
File "/System/Library/Frameworks/Python.framework/Versions/2.5/lib/python2.5/re.py", line 233, in _compile
raise error, v # invalid expression
sre_constants.error: nothing to repeat
Toutefois (\s*\1)
ne doit pas être nul, mais nous le savons uniquement parce que nous savons ce qu'il y a dans\1. Apparemment python ne fait pas ... c'est bizarre.
C'est un bug Python entre "*" et les caractères spéciaux.
Au lieu de
re.compile(r"\w*")
Essayer:
re.compile(r"[a-zA-Z0-9]*")
Cela fonctionne, mais ne fait pas la même expression régulière.
Ce bug semble avoir été corrigé entre 2.7.5 et 2.7.6.
Ce n'est pas seulement un bug Python avec * en fait, cela peut aussi se produire lorsque vous passez une chaîne en tant que partie de votre expression régulière à compiler, comme;
import re
input_line = "string from any input source"
processed_line= "text to be edited with {}".format(input_line)
target = "text to be searched"
re.search(processed_line, target)
cela provoquera une erreur si la ligne traitée contenait des "(+)" par exemple, comme vous pouvez le trouver dans les formules chimiques, ou de telles chaînes de caractères. la solution est de s'échapper mais lorsque vous le faites à la volée, il peut arriver que vous ne le fassiez pas correctement ...
Au-delà du bogue découvert et corrigé, je noterai simplement que le message d'erreur sre_constants.error: nothing to repeat
est un peu déroutant. J'essayais d'utiliser r'?.*'
comme modèle, et pensait qu'il se plaignait pour une raison étrange de *
, mais le problème est que ?
est une façon de dire "répéter zéro ou une fois". Je devais donc dire r'\?.*'
pour correspondre à un littéral ?