Можете ли вы объяснить мне, как это работает? Вот пример:
<!-- The quick brown fox
jumps over the lazy dog -->
<!--[if IE 7]>
<link rel="stylesheet" type="text/css" href="/supersheet.css" />
<![endif]-->
<!-- Pack my box with five dozen liquor jugs -->
Сначала я попытался использовать следующее регулярное выражение для сопоставления содержимого внутри условных комментариев:
/<!--.*?stylesheet.*?-->/s
Не удалось, так как регулярное выражение соответствует всему содержимому до первого <!--
и последнее -->
, Затем я попытался использовать другой шаблон с предварительным утверждением:
/<!--(?=.*?stylesheet).*?-->/s
Это работает и соответствует именно то, что мне нужно. Тем не менее, следующее регулярное выражение также работает:
/<!--(?=.*stylesheet).*?-->/s
Последнее регулярное выражение не имеет неохотного квантификатора в предварительном утверждении. И теперь я в замешательстве. Может кто-нибудь объяснить мне, как это работает? Может быть, есть лучшее решение для этого примера?
Обновлено:
Я попытался использовать регулярные выражения с утверждением в другом документе, но он не смог обработать содержимое между комментариями. Итак, этот /<!--(?=.*?stylesheet).*?-->/s
(а также этот /<!--(?=.*stylesheet).*?-->/s
) не является правильным. Не используйте его и попробуйте другие предложения.
Обновлено:
Решение было найдено Джонни 5 (см. ответ). Он предложил три варианта:
/style-sheet.css
, она не будет работать.\K
, Отлично работает. Недостатками являются следующие:
Я думаю, что следующее является хорошим решением для моего примера:
/(?s)<!--(?:(?!<!).)+?stylesheet.+?-->/
То же самое, но с s
модификатор в конце:
/<!--(?:(?!<!).)+?stylesheet.+?-->/s
Как я уже сказал, это хорошее решение, но мне удалось улучшить шаблон и найти другое, которое в моем случае работает быстрее.
Итак, окончательное решение заключается в следующем:
/<!--(?:(?!-->).)+?stylesheet.+?-->/s
Спасибо всем участникам за интересные ответы.
Соответствовать только части <!--
…stylesheet
…-->
Есть много способов:
1.) Используйте отрицается дефис [^-]
ограничить матч и остаться между <!--
а также stylesheet
(?s)<!--[^-]+stylesheet.+?-->
[^-]
разрешает только символы, которые не являются дефисами. Увидеть тест на regex101.
2.) Чтобы получить «последний» или ближайший матч без особых усилий, также можно поставить жадный точка прежде чем ᗧ есть. Имеет смысл, если не соответствует глобально / только один элемент для сопоставления. использование \ K для сброса после жадности:
(?s)^.*\K<!--.+?stylesheet.+?-->
Увидеть тест на regex101. Также можно использовать захватить группу и захватить 1 доллар: (?s)^.*(<!--.+?stylesheet.+?-->)
3.) Используя смотреть вперед сужать его обычно дороже:
(?s)<!--(?:(?!<!).)+?stylesheet.+?-->
Увидеть тест на regex101. (?!<!).
смотрит вперед на каждого персонажа между <!--
а также stylesheet
если не начать другой <!
… чтобы остаться внутри одного элемента. Похоже на отрицание дефиса.
Вместо .*
я использовал .+
за один или больше — зависит от того, что должно быть сопоставлено. Вот +
подходит лучше.
Какое решение использовать, зависит от точных требований. Для этого случая я бы использовал первый.
Строка stylesheet
упоминается только один раз в вашем тестовом документе, поэтому оба используемых вами регулярных выражения будут совпадать, но по-разному.
<!--(?=.*?stylesheet).*?-->/s
Этот делает следующее:
<!--
,stylesheet
, Сбой, если не найден.-->
,<!--(?=.*stylesheet).*?-->/s
Этот делает следующее:
<!--
,stylesheet
, Сбой, если не найден.-->
,По сути, нужно значительно отказаться, а другой нет.
Если ваша тема вместо этого …
<! - Быстрая коричневая лиса перепрыгивает через ленивую собаку -> <! - [если IE 7]> <ссылка rel = "таблицы стилей"type =" text / css "href =" / supersheet.css "/> <! [ENDIF] -> <! - возьми мою коробку с пятью дюжинами таблицы стилейs ->
вы получите два разных результата. Первый найдет первый stylesheet
в то время как последний найдет второй (и последний), так как он начинает поиск с конца строки.