Во-первых, отказ от ответственности: любая попытка нарезать и нарезать кубиками XML с помощью регулярных выражений является хрупкой; настоящий парсер XML будет лучше.
Узор:
\(<Annotation\(\s*\w\+="[^"]\{-}"\s\{-}\)*>\)\@<=\(\(<\/Annotation\)\@!\_.\)\{-}"MATCH\_.\{-}\(<\/Annotation>\)\@=
Давайте разберемся с этим ...
Группа 1 - <Annotation\(\s*\w\+="[^"]\{-}"\s\{-}\)*>
. Соответствует начальному тегу элемента Attribute. Группа 2, которая встроена в Группу 1, соответствует атрибуту и может повторяться 0 или более раз.
Группа 2 - \s*\w\+="[^"]\{-}"\s\{-}
. Большинство из этих частей обычно используются; наиболее необычным является \{-}
, что означает не жадное повторение (*?
в Perl-совместимых регулярных выражениях). Нежадное совпадение пробелов в конце важно для производительности; без него Vim попытается всеми возможными способами разделить пробелы между атрибутами между \s*
в конце группы 2 и \s*
в начале следующего вхождения группы 2.
За Группой 1 следует \@<=
. Это позитивный взгляд нулевой ширины. Он предотвращает включение начального тега в сопоставляемый текст (например, для s ///).
Группа 3 - \(<\/Annotation\)\@!\_.
. Он включает в себя группу 4, которая соответствует началу конечного тега атрибута. \@!
является отрицательным прогнозом нулевой ширины, а \_.
соответствует любому символу (включая символы новой строки). Вместе эти группы соответствуют любому символу, кроме того, где начинается конечный тег атрибута. За Группой 3 следует жадный маркер повторения \{-}
, чтобы он соответствовал наименьшему блоку текста перед МАТЧ. Если бы вы использовали \_.
вместо группы 3, сопоставляемый текст мог бы включать конечный тег элемента Annotation, который включал not , включая MATCH и продолжался до следующего элемента Annotation с MATCH. (Попробуйте.)
Следующий бит прост: найдите MATCH и минимальное количество других символов перед конечным тегом.
Группа 5 проста: это конечный тег. \@=
является положительным прогнозом нулевой ширины, который включен сюда по той же причине, что и \@<=
для начального тега. Мы должны повторить <\/Attribute
вместо использования \4
, потому что группы с модификаторами нулевой ширины не фиксируются.