РЕДАКТИРОВАТЬ: Как правильно отмечает @Kobi в комментариях, гораздо более простая версия оригинального сообщения ниже, конечно:
<(tagstart)>(.*?)</\1>
Поскольку оригинальная версия также работает, а все остальные утверждения остаются верными, я оставлю все как есть.
Если ( и только если ) теги не могут быть вложенными:
<(tagstart)>((?:(?!</\1>).)*)</\1>
Пояснение:
<(tagstart)> # matches "<tagstart>" and stores "tagstart" in group 1
( # begin group 2
(?: # begin non-capturing group
(?! # begin negative look-ahead (... not followed by)
</\1> # a closing tag with the same name as group 1
) # end negative look-ahead
. # if ok, match the next character
)* # end non-capturing group, repeat
) # end group 2 (stores everything between the tags)
</\1> # a closing tag with the same name as group 1
Регулярное выражение необходимо применять в режиме «одной строки» (иногда его называют режимом «точка»). Либо это, либо вы заменяете .
на [\s\S]
.
Для общего сопоставления текста между любыми двумя тегами с одинаковыми именами используйте <(\w+)>
вместо <(tagstart)>
.
В зависимости от вашего вкуса регулярных выражений некоторые вещи могут работать по-разному, например $1
вместо \1
для обратных ссылок или метасимволы, которые требуют дополнительного экранирования.
См. Rubular demo .