2017-01-26 11 views
1

Я хотел бы использовать функцию замены vim (:% s) для поиска и замены определенного кода кода. Например, если у меня есть код, подобный следующему:Заменить оператор C заменой в vim

if(!foo) 

Я хотел бы заменить его:

if(foo == NULL) 

Однако Foo это всего лишь пример. Имя переменной может быть любым.

Это то, что я придумал для моей команды VIM: «*»

:%s/if(!.*)/if(.* == NULL)/gc 

Он ищет заявления правильно, но он пытается заменить его вместо переменной, которая там (т.е. «Foo «). Есть ли способ сделать то, что я прошу с помощью vim?

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

Заранее благодарен!

ответ

5

Вы должны использовать захвата группировки и ссылочность для того, чтобы добиться того, что:

 Pattern  String sub. flags 
    |---------| |------------| |-| 
:%s/if(!\(.*\))/if(\1 == NULL)/gc 
  |---| |--| 
      |  ^
      |________| 
The matched string in pattern will be exactly repeated in string substitution 

:help /\(

\(\) A pattern enclosed by escaped parentheses.     /\(/\(\) /\) 
     E.g., "\(^a\)" matches 'a' at the start of a line. 
     E51 E54 E55 E872 E873 

\1  Matches the same string that was matched by      /\1 E65 
     the first sub-expression in \(and \). {not in Vi} 
     Example: "\([a-z]\).\1" matches "ata", "ehe", "tot", etc. 
\2  Like "\1", but uses second sub-expression,      /\2 
    ...                 /\3 
\9  Like "\1", but uses ninth sub-expression.      /\9 
     Note: The numbering of groups is done based on which "\(" comes first 
     in the pattern (going left to right), NOT based on what is matched 
     first. 
2

Вы можете использовать

:%s/if(!\(.*\))/if(\1 == NULL)/gc

Поставив. * В \ (\) вы делаете пронумерованных захватили группу, которая означает, что регулярное выражение будет захватывать то, что в. * Когда начинается тогда заменить используя \ 1, вы напечатаете захваченную группу.

0

Попробуйте следующее:

%s/if(!\(.\{-}\))/if(\1 == NULL)/gc 

Квантификатор .\{-} соответствует непустое слово, как можно (более строгий, чем .*).

Паранетекс \(10 и \) используются для разделения найденного выражения на подвыражения, так что вы можете использовать эти подгруппы в заменяющей строке.

И наконец, \1 позволяет пользователю использовать первое подвыраженное подвыражение, в нашем случае это то, что попадает в парантез.

Надеюсь, что это более понятно, более подробную информацию можно найти here. И спасибо за комментарий, который предлагает улучшить ответ.

+0

Не могли бы вы дать нам некоторые объяснения о том, что здесь происходит? В противном случае мы продолжаем в зависимости от вас помощь в подобных ситуациях, неправда? Спасибо за помощь! – SergioAraujo

0

Макрос легко в этом случае, просто сделайте следующее:

qa .............. starts macro 'a' 
f! .............. jumps to next '!' 
x ............... erase that 
e ............... jump to the end of word 
a ............... starts append mode (insert) 
== NULL ........ literal == NULL 
<ESC> ........... stop insert mode 
q ............... stops macro 'a' 

:%norm @a ........ apply marco 'a' in the whole file 
:g/^if(!/ norm @a apply macro 'a' in the lines starting with if...