Как именно работает притяжательный квантификатор?

В конце страницы есть попытка объяснить, как работают жадные, неохотные и притяжательные квантификаторы: http://docs.oracle.com/javase/tutorial/essential/regex/quant.html

Однако я попробовал себе пример и, кажется, не понимаю его полностью.

Я вставлю свои результаты напрямую:

Enter your regex: .*+foo
Enter input string to search: xfooxxxxxxfoo
No match found.

Enter your regex: (.*)+foo
Enter input string to search: xfooxxxxxxfoo
I found the text "xfooxxxxxxfoo" starting at index 0 and ending at index 13.

Почему первый рег.эксп. не находит совпадений, а второй делает? В чем точная разница между этими двумя рег.эксп.?


person Ariel    schedule 06.12.2013    source источник


Ответы (2)


+ после другого квантификатора означает «не позволять механизму регулярных выражений возвращаться к тому, с чем совпал предыдущий токен». (См. руководство по притяжательным квантификаторам здесь).

Поэтому, когда вы применяете .*foo к "xfooxxxxxxfoo", .* сначала соответствует всей строке. Затем, поскольку foo не может быть сопоставлено, механизм регулярных выражений откатывается до тех пор, пока это не станет возможным, достигая совпадения, когда .* соответствует "xfooxxxxxx", а foo соответствует "foo".

Теперь дополнительные + предотвращают откат, поэтому совпадение не удается.

Когда вы пишете (.*)+foo. + приобретает совершенно другое значение; теперь это означает «один или несколько предыдущих токенов». Вы создали вложенные квантификаторы, что, кстати, не очень хорошая идея. Если вы примените это регулярное выражение к такой строке, как "xfoxxxxxxxxxfox", вы столкнетесь с катастрофическим возвратом.

person Tim Pietzcker    schedule 06.12.2013
comment
Ваш ответ дал мне больше, чем я просил. Я думаю, что это объясняет все, что нужно знать о квантификаторах. - person Ariel; 06.12.2013
comment
@Ariel: Спасибо, но квантификаторов гораздо больше, чем это :) - person Tim Pietzcker; 06.12.2013
comment
Как, например? Что еще нужно знать о квантификаторах? - person Ariel; 06.12.2013
comment
@Ariel: Например, разница между ленивым и жадным сопоставлением очень важна. Затем есть *, +, ? и {n,m} на выбор, каждый из которых можно сделать притяжательным или ленивым. См. regular-expressions.info/refrepeat.html. - person Tim Pietzcker; 06.12.2013

Притяжательный квантификатор берет всю строку и проверяет, соответствует ли она, если нет, то не удается. В вашем случае xfooxxxxxxfoo соответствует .*+, но затем вы запрашиваете другой foo, которого нет, поэтому сопоставитель не работает.

Жадный квантификатор сначала делает то же самое, но вместо того, чтобы потерпеть неудачу, он «отступает» и пытается снова:

xfooxxxxxxfoo fail
xfooxxxxxxfo fail
xfooxxxxxxf fail
xfooxxxxxx match

Во втором регулярном выражении вы запрашиваете что-то еще, путая механизм группировки. Вы запрашиваете «одно или несколько совпадений (.*)», поскольку + теперь относится к () и есть одно совпадение.

person TwoThe    schedule 06.12.2013