web-dev-qa-db-fra.com

erreur d'expression régulière - rien à répéter

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?

57
goh

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.

40
mb14

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.

14
Franklyn

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 ...

5
Ando Jurai

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 ?

3
nealmcb