<select[^>]*>[^<]*(?:<(?!/select>)[^<]*)*</select>
... или в читаемой человеком форме:
<select[^>]*> # start tag
[^<]* # anything except opening bracket
(?: # if you find an open bracket
<(?!/select>) # match it if it's not part of end tag
[^<]* # consume any more non-brackets
)* # repeat as needed
</select> # end tag
Это пример техники "развернутой петли", которую Фридл развивает в своей книге Освоение регулярных выражений . Я провел быстрый тест в RegexBuddy, используя шаблон, основанный на неохотных квантификаторах:
(?s)<select[^>]*>.*?</select>
... и понадобилось около 6000 шагов, чтобы найти совпадение. Шаблон unrolled-loop занял всего 500 шагов. И когда я удалил закрывающую скобку из конечного тега (</select
), сделав сопоставление невозможным, потребовалось всего 800 шагов, чтобы сообщить об ошибке.
Если ваш тип регулярных выражений поддерживает собственнические квантификаторы, используйте их также:
<select[^>]*+>[^<]*+(?:<(?!/select>)[^<]*+)*+</select>
Требуется примерно такое же количество шагов для достижения соответствия, но он может использовать намного меньше памяти в процессе. И если совпадение невозможно, оно проваливается еще быстрее; в моих тестах потребовалось около 500 шагов, столько же, сколько и для поиска соответствия.