2010-09-09 4 views
46

je reçois un message d'erreur lorsque j'utilise cette expression:erreur regex - rien à redire

re.sub(r"([^\s\w])(\s*\1)+","\\1","...") 

J'ai vérifié les expressions rationnelles RegExr et il retourne . comme prévu. Mais quand je l'essaie en Python, je reçois ce message d'erreur:

raise error, v # invalid expression 
sre_constants.error: nothing to repeat 

Quelqu'un peut-il expliquer?

+3

Si quelqu'un obtient cette erreur pour * sans raison apparente *, assurez-vous que la version de Python utilisée lors de la création de votre virtualenv correspond toujours à la version de l'interpréteur installé globalement (par exemple, ancien vritualenv créé avant la mise à niveau de Python vers une version plus récente.) – hayavuk

+0

@bvukelic Comment est-ce que je réajusterais pour qu'ils soient identiques? –

+0

Je viens de détruire l'env existant, et je l'ai recréé. – hayavuk

Répondre

32

Il semble être 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 ont un sens, parce que 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 

Cependant (\s*\1) ne devrait pas être nul, mais nous savons seulement parce que nous savons ce qui est dans \ 1. Apparemment, python ne ... c'est bizarre.

+0

Encore plus bizarre est que '([^ \ s \ w]) (\ 1) +' * does * fonctionne. –

+0

@alan: oui, je l'ai remarqué aussi. – mb14

+0

si c'est le cas, y a-t-il une solution? – goh

9

C'est un bug Python entre "*" et les caractères spéciaux.

Au lieu de

re.compile(r"\w*") 

Essayez:

re.compile(r"[a-zA-Z0-9]*") 

Il fonctionne, ne permet toutefois pas la même expression régulière.

Ce bug semble avoir été corrigé entre 2.7.5 et 2.7.6.

2

Ce n'est pas seulement un bug Python avec * en réalité, il peut aussi arriver quand vous passez une chaîne dans le cadre 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 certaines « (+) », par exemple, comme vous pouvez trouver dans les formules chimiques, ou de telles chaînes de caractères. la solution est d'échapper mais quand vous le faites à la volée, il peut arriver que vous échouez à le faire correctement ...

0

Au-delà du bug qui a été découvert et corrigé, je vais juste noter que le message d'erreur sre_constants.error: nothing to repeat est un peu déroutant. J'essayais d'utiliser r'?.*' comme un motif, et je pensais qu'il se plaignait pour une raison étrange au sujet de *, mais le problème est en fait que ? est une façon de dire "répéter zéro ou une fois". Donc, je devrais dire r'\?.*' pour correspondre à un littéral ?