разница в совпадении из-за позиции отрицательного просмотра вперед?

У меня много путаницы в регулярных выражениях, и я пытаюсь их решить. Здесь у меня есть следующая строка:

{start}do or die{end}extended string

Два моих разных регулярных выражения, в которых я изменил только положение точки:

(.(?!{end}))* //returns: {start}do or di
                                      //^ See here
((?!{end}).)* //returns: {start}do or die
                                      //^ See here

Почему первое регулярное выражение съедает последнее «e»?

А также как этот отрицательный просмотр вперед делает этот квантификатор * не жадным? Я имею в виду, почему он не может потреблять символы после {end}?


person AL-zami    schedule 17.07.2015    source источник


Ответы (2)


С вашим негативным прогнозом вы говорите, что невозможно сопоставить регулярное выражение, которое в вашем случае: {end}. И . захватывает все, кроме новой строки.

Итак, с вашим первым регулярным выражением:

(.(?!{end}))*

Он пропускает e, потому что: e{end} не может соответствовать из-за отрицательного просмотра вперед. В то время как во втором регулярном выражении, где у вас есть точка на другой стороне, это может быть до тех пор, пока: {end}d поэтому e не будет включено во второе регулярное выражение.

person Rizier123    schedule 17.07.2015
comment
Благодарность ! а можно немного поконкретнее? почему e{end} не будет совпадать из-за отрицательного прогноза. Разве это не должно быть только {end}? - person AL-zami; 17.07.2015
comment
@AL-zami . сам по себе жадный, поэтому будет стараться максимально соответствовать. Итак: {start}do or die не будет работать из-за легативного просмотра вперед, но он устает, чтобы соответствовать как можно большему количеству, и это: {start}do or di только без e, потому что он не соответствует просмотру вперед. Во втором случае то же самое, ожидайте, что вы поменяли местами некоторые вещи, поэтому он снова пытается максимально соответствовать: {start}do or die{end}e и здесь снова это не работает из-за просмотра вперед. Таким образом, это закончится: {start}do or die где просмотр вперед не совпадает. (Утверждения никогда не совпадают) - person Rizier123; 17.07.2015
comment
@ AL-zami Итак, где мы сейчас с этим вопросом? - person Rizier123; 17.07.2015
comment
все еще пытаюсь обернуть мою голову вокруг этого. На самом деле было бы лучше, если бы я мог понять, что происходит внутри движка регулярных выражений во время матча ... мне трудно понять это! - person AL-zami; 17.07.2015
comment
@AL-zami Отрицательный прогноз говорит, что невозможно сопоставить регулярное выражение, которое в вашем случае: (?! {end} ) . И . соответствует всему, кроме новой строки. Итак, в вашем первом регулярном выражении: [Everything except new line][Everything but not: {end}] это регулярное выражение не может соответствовать: [...]e{end}[...] Потому что {end} есть. Так что это заканчивается на [...]di[... (not {end} matched here)], потому что это может соответствовать этому. Во втором регулярном выражении: [...]{end}e[...] можно сопоставить, потому что перед e из die нет {end}. Но это заканчивается: {end}e Это не может соответствовать этому. - person Rizier123; 17.07.2015
comment
я кое-что прочитал и попытался понять ваш ответ. Я создал рабочий процесс для механизма регулярных выражений для обоих регулярных выражений. Я добавил его ниже в качестве ответа, так как он довольно большой для раздела комментариев. Не могли бы вы взглянуть на это и проверить, правильно это или нет :) - person AL-zami; 19.07.2015
comment
@AL-zami Поскольку теперь вы понимаете, что происходит, я надеюсь, вы также лучше понимаете мой ответ и то, что я имел в виду. - person Rizier123; 19.07.2015

Я понял рабочий процесс для механизма регулярных выражений как для регулярного выражения при выполнении задачи...

Во-первых, для (.(?!{end}))* подход к механизму регулярных выражений выглядит следующим образом...

"{start}do or die{end}extended string"
^   .(dot) matches "{" and {end} tries to match here but fails.So "{" included
"{start}do or die{end}extended string"
 ^  . (dot) matches "s" and {end} tries to match here but fails.So "s" included

....
....so on...
"{start}do or die{end}extended string"
               ^ (dot) matches "e" and {end} here matches "{end}" so "e" is excluded..
so the match we get is "{start}do or di"

для второго регулярного выражения ((?!{end}).)*....

"{start}do or die{end}extended string"
^ {end} regex tries to match here but fails to match.So dot consumes "{".

"{start}do or die{end}extended string"
 ^ {end} regex tries to match here but fails again.So dot consumes "s".

....
..so on..
"{start}do or die{end}extended string"
               ^   {end} regex tries to match here but fails.So dot consumes the "e"
"{start}do or die{end}extended string"
                ^   {end} regex tries to match here and succeed.So the whole regex fail here.

So we ended up with a match which is "{start}do or die"
person AL-zami    schedule 19.07.2015
comment
Точно, вы поняли! Мне также нравится, как вы это показываете. - person Rizier123; 19.07.2015