Используя рубин regexp я получаю следующие результаты:
>> 'foobar'[/o+/]
=> "oo"
>> 'foobar'[/o*/]
=> ""
Но:
>> 'foobar'[/fo+/]
=> "foo"
>> 'foobar'[/fo*/]
=> "foo"
В документации говорится:
*: нуль или больше повторений предыдущего
+: одно или несколько повторений предыдущего
Таким образом, я ожидаю, что 'foobar' [/o*/] возвращает тот же результат как 'foobar' [/o +/]
Делает у кого-либо есть объяснение этого
'foobar' [/ o * /]
соответствует нулю o
s перед f
, в позиции 0
'foobar' [/ o + /]
не может соответствовать там, потому что должно быть как минимум 1 o
, поэтому вместо этого он соответствует всем ] o
s с позиции 1
В частности, вы видите совпадения
'foobar' [/ o * /]
=>
'<> foobar'
'foobar '[/ o + /]
=>
' f
Это распространенное непонимание того, как работает regexp.
Хотя * жадный и не закреплен в начале строки, механизм regexp все равно начнет искать с начала строки. В случае "/o+/" он не совпадает с позицией 0 (например. «f»), но поскольку + означает одно или несколько, оно должно продолжать сопоставление (это не имеет ничего общего с жадностью) до тех пор, пока не будет найдено совпадение или не будут оценены все позиции.
Однако в случае "/o*/", который, как вы знаете, означает 0 или более раз, когда он не совпадает в позиции 0, механизм regexp будет корректно останавливаться в этой точке (как и должно быть, потому что o* просто означает, что o является необязательным). Есть также причины производительности, поскольку «o» является необязательным, зачем тратить больше времени на его поиск?