2010-03-24 6 views
7

En utilisant Ruby regexp-je obtenir les résultats suivants:Ruby Regexp: + vs *. comportement spécial?

>> 'foobar'[/o+/] 
=> "oo" 
>> 'foobar'[/o*/] 
=> "" 

Mais:

>> 'foobar'[/fo+/] 
=> "foo" 
>> 'foobar'[/fo*/] 
=> "foo" 

La documentation dit:
*: zéro ou plusieurs répétitions des précédentes
+: une ou plusieurs répétitions de la précédente

Donc, je m'attends à ce que 'foobar' [/ o * /] renvoie le même résultat que 'foobar' [/ o + /]

Quelqu'un at-il une explication à cela

Répondre

14

'foobar'[/o*/] est correspondant à zéro o s qui apparaissent avant la f, à la position 0
'foobar'[/o+/] ne peut pas y répondre, car il doit y avoir au moins 1 o, il correspond à la place tous les o s de la position 1

Plus précisément, les matches que vous voyez sont

'foobar'[/o*/]=>'<>foobar'
'foobar'[/o+/]=>'f<oo>bar'

3

Ceci est une mauvaise compréhension commune de la façon dont fonctionne regexp.

Bien que le * soit gourmand et ne soit pas ancré au début de la chaîne, le moteur de regexp commencera toujours à regarder depuis le début de la chaîne. Dans le cas de "/ o + /", il ne correspond pas à la position 0 (par exemple "f"), mais puisque le + signifie un ou plusieurs, il doit continuer à correspondre (cela n'a rien à voir avec la gourmandise) jusqu'à la correspondance est trouvée ou toutes les positions sont évaluées. Cependant, dans le cas de "/ o * /", qui, comme vous le savez, signifie 0 ou plusieurs fois, lorsqu'il ne correspond pas à la position 0, le moteur d'expression rationnelle s'arrêtera à ce point (comme il se doit). car o * signifie simplement que le o est optionnel). Il y a aussi des raisons de performance, puisque "o" est optionnel, pourquoi passer plus de temps à le chercher?