Было бы полезно, если бы мы знали, какой язык или инструмент вы используете; существует множество различий в синтаксисе, семантике и возможностях. Вот один из способов сделать это на 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 мне пришлось писать для этого собственный цикл.
Таким образом, можно выполнить эту работу с одним регулярным выражением, но это очень сложно, и регулярное выражение, и окружающий его код должны быть адаптированы к языку, с которым вы работаете.
person
Alan Moore
schedule
05.12.2008