Было бы полезно, если бы мы знали, какой язык или инструмент вы используете; Есть много вариантов синтаксиса, семантики и возможностей. Вот один из способов сделать это на Java:
String str = "<y>c</y>...<x>...<y>a</y>...<y>b</y>...</x>...<y>d</y>";
String regex = "<y[^>]*+>(?=(?:[^<]++|<(?!/?+x\\b))*+</x>)(.*?)</y>";
Matcher m = Pattern.compile(regex).matcher(str);
while (m.find())
{
System.out.println(m.group(1));
}
После того, как я сопоставил <y>
, я использую прогноз, чтобы подтвердить, что где-то впереди есть </x>
, но между текущей позицией и ней нет <x>
. Предполагая, что псевдо-HTML достаточно хорошо сформирован, это означает, что текущая позиция совпадения находится внутри элемента "x".
Я интенсивно использовал притяжательные квантификаторы, потому что они делают такие вещи намного проще, но, как вы можете видеть, регулярное выражение все еще немного монстр. Помимо Java, единственными известными мне разновидностями регулярных выражений, поддерживающими квантификаторы поддержки, являются PHP и инструменты JGS (RegexBuddy / PowerGrep / EditPad Pro). С другой стороны, многие языки предоставляют способ получить все совпадения одновременно, но в Java мне пришлось написать свой собственный цикл для этого.
Так что возможно выполнить эту работу с одним регулярным выражением, но очень сложным, и и регулярное выражение, и прилагаемый код должны быть адаптированы к языку, на котором вы работаете.