Почему "abcdef" не соответствует (?=abc) def, но соответствует abc(?=def)? [дубликат]

этот вопрос уже есть ответ здесь:

в Javascript у меня есть строка abcdef и не может понять это странное поведение:

  • (?=abc)def не соответствует строке
  • abc(?=def) не соответствует строка

почему?

4 ответов


на (?=abc)def на (?=abc) захват равен нулевой ширине и не перемещает курсор вперед во входной строке после успешного совпадения. Эта конструкция просто говорит, что посмотрите вперед на следующие три символа, чтобы увидеть, являются ли они abc, если они затем проверить, если те же символы def. В этот момент матч терпит неудачу..

вам нужно понять, как работает движок regex, чтобы завершить матч. Рассмотрим вашу входную строку abcdef и ваше регулярное выражение abc(?=def). Двигатель запускается путем сопоставления a затем перемещает курсор внутри входной строки на следующий символ и пытается соответствовать b потому что курсор во входной строке включен b матч успешно. Затем движок перемещает курсор внутри входной строки и пытается сопоставить c и потому, что курсор находится в строке ввода находится на c совпадение завершается успешно, и курсор во входной строке снова перемещается на следующий символ. Теперь двигатель встречает (?=def) в этот момент движок просто смотрит вперед, чтобы увидеть, являются ли следующие три символа из того места, где курсор находится во входном жале, на самом деле def без перемещения курсора, которым они являются, и матч завершается успешно.

теперь рассмотрим входную строку xyz и символов x(?=y)Z. Движок регулярных выражений помещает курсор на первую букву во входной строке и проверяет, что это x и считает, что x так он двигает курсор к следующему символу в строке ввода. Теперь он смотрит вперед, чтобы увидеть, является ли следующий символ y, который он есть, но движок не перемещает предисловие курсора ввода текста, поэтому курсор во входном тексте остается на y. Далее движок смотрит, находится ли курсор на букве z, но потому что курсор во входном тексте все еще находится на букве y матч не удался.

вы можете прочитать намного больше о положительных и отрицательных lookaheads на http://www.regular-expressions.info/lookaround.html


(?=...) - Это lookahead, другими словами, который проверяет строку справа. Обратите внимание также, что lookahead-это утверждение нулевой ширины, которое не ест символ. В первом примере: (?=abc) что означает следует abc встречи def. Именно по этой причине модель терпит неудачу.

в вашем втором примере он находит def после abc, затем строка сопоставляется


основываясь на вашем ответе на мой комментарий, Я думаю, что вы хотите позитивный взгляд-за:

(?<=abc)def

Edit:

поскольку вы используете JavaScript (извините, я только прочитал Ваш вопрос-я не смотрел на теги), почему бы просто не использовать обычную группу захвата и не включить совпадение в шаблон замены?

"abcdef".replace(/(abc)def/, "")

MDN определение lookaheads в javascript

x(?=y)
Совпадает с 'X' только если 'X' не следует 'y'. Это называется упреждение.

например, /Jack(?=Sprat)/ соответствует "Jack", только если за ним следует "килька". /Jack(?=Sprat|Frost)/ соответствует 'Jack', только если за ним следует 'sprat' или 'Frost'. Однако ни "килька", ни "мороз" не являются частью результатов матча.

так (?=y) предшествует другой оператор, в в этом случае пустая строка, тогда она будет совпадать только в том случае, если за первым оператором следует второй. Без ведущего утверждения выражение (?="abc") будет соответствовать на первых 3 символов abc без захвата их, а затем проверить еще раз, чтобы увидеть, если эти символы def, который не удастся.