2014-12-29 5 views
2

У меня есть большой XML-файл с существенной информацией, закомментированной по какой-то глупой причине, которую автор решил сделать.Заменить до и после строки в vim

Это похоже на следующее:

<book id="cat2" type="t" group="1234"> <!-- Group Name --> 
    <book id='ABC123' type='s'/> <!-- NameOfBookHere --> 
    <book id='etc456' type='s'/> <!-- Harry Potter --> 
    <book id='XYZ234' type='s'/> <!-- Jurassic Park --> //Notice variable space before the comment tag. 
</book> 

Я хотел бы быть в состоянии сделать замену на основе первой замены. Вот что я пробовал.

  1. Мне нужно избавиться от исходного тега комментария. Я пробовал: :%s/\/> \+<!--/name="
  2. Стараюсь другой подобный один для тегов, которые не закрывающиеся :%s/> \+<!--/name="
  3. Затем замените остальные: %s/ -->/"\/>

Результаты являются чем-то вроде этого:

<book id="cat2" type="t" group="1234" name="Group Name"/> 
    <book id='ABC123' type='s' name="NameOfBookHere"/> 
    <book id='etc456' type='s' name="Harry Potter"/> 
    <book id='XYZ234' type='s' name="Jurassic Park"/> 
</book> 

К сожалению, это влияет на теги <book> с атрибутом group в нем, которые не являются само закрытием.

Это означает, что у меня остались тысячи самозакрывающихся тегов <book>, которые не должны быть закрывающимися тегами xml. Конечно, их невозможно вручную удалить.

Есть ли способ сделать другую замену на основе строк, на которые повлияла первая замена? Или есть другое решение моей проблемы?

ответ

3
:%s#\v(\>|/\>)\s*\<!--\s*(.{-})\s*--\># name="\2"\1# 

С:

  • %s: заменой на всех линиях
  • #: альтернативный разделитель (особенно полезно при редактировании XML)
  • \v: использовать режим VeryMagic (см :h magic)
  • (\>|/\>): захват либо >, либо />
  • \s*: 0-н пробельные символы
  • \<!--\s*(.{-})\s*--\>: захватить текст комментария ({-} является Vim, нежадным * (по аналогии с *? это другие языки))
  • #: конец регулярного выражения
  • name="\2"\1: вставить «имя =„текст комментария“» и заканчиваются разделителем вы первым захваченным

EDIT:

Как Петр Rincker сказал, что вы можете использовать «ноль или один» (обычно \=/\? или =/? если очень магия на) квантор в первой группе указывают на возможное присутствие /:

:%s#\v(/?\>)\s*\<!--\s*(.{-})\s*--\># name="\2"\1# 
+3

Нет необходимости в чередовании в этой первой группе захвата. Просто используйте '\ =' (используя 'magic'). '\ =' соответствует 0 или 1 как можно больше. Подобно Perl's '?'. например ':% S # \ v (/ = \>) ...' –

Смежные вопросы