Как переформатировать исходный файл, чтобы перейти от 2 пробелов к 3? - PullRequest
8 голосов
/ 21 июня 2011

Этот вопрос почти идентичен этому вопросу , за исключением того, что мне нужно перейти к трем пробелам (руководящим принципам кодирования компании), а не к четырем, и принятое решение только удвоит соответствующий шаблон.Вот моя первая попытка:

:%s/^\(\s\s\)\+/\1 /gc 

Но это не работает, потому что четыре пробела заменяются тремя.Поэтому я думаю, что мне нужен какой-то способ подсчитать, сколько раз шаблон соответствует «+», и использовать это число для создания другой стороны подстановки, но я чувствую, что эта функциональность, вероятно, недоступна в регулярном выражении Vim (я знаю, если вы думаете, что это возможно).

Я также пытался выполнить замену вручную, заменяя сначала самые большие отступы, а затем следующий меньший отступ, пока я не преобразовал все это, но это было трудно отследитьпробелы:

:%s/^              \(\S\)/                     \1/gc

Я мог бы отправить его через Perl, так как кажется, что Perl мог бы делать это с помощью Расширенных паттернов .Но я не мог заставить его работать с моей версией Perl.Вот моя попытка подсчитать число:

:%!perl -pe 'm<(?{ $cnt = 0 })(a(?{ local $cnt = $cnt + 1; }))*aaaa(?{ $res = $cnt })>x; print $res'

Мое последнее прибежище - написать скрипт Perl для преобразования, но я надеялся на более общее решение в Vim, чтобы я мог повторно использоватьИдея решить другие вопросы в будущем.

Ответы [ 2 ]

8 голосов
/ 21 июня 2011

Позвольте vim сделать это за вас?

:set sw=3<CR>
gg=G

Первая команда устанавливает опцию shiftwidth, которая определяет, сколько отступов вы делаете.Во второй строке написано: перейти в начало файла (gg) и сделать повторный отступ (=) до конца файла (G).

Конечно, это зависит от vimиметь хороший форматер для языка, который вы используете.Что-то может запутаться, если нет.

Способ регулярного выражения ... Безопаснее, но менее понятно:

:%s#^\(\s\s\)\+#\=repeat(' ',strlen(submatch(0))*3/2)#g

(мне пришлось провести некоторые эксперименты.)

Двабаллы:

  • Если замена начинается с \=, она оценивается как выражение.
  • Вы можете использовать много вещей вместо /, поэтому / доступнодля деления.
1 голос
/ 21 июня 2011

Версия Perl, которую вы запросили ...

Из командной строки (редактирование на месте, без резервного копирования):

bash$ perl -pi -e 's{^((?:  )+)}{"   " x (length($1)/2)}e' YOUR_FILE

(на месте, резервное копирование оригинала в"YOUR_FILE.bak"):

bash$ perl -pi.bak -e 's{^((?:  )+)}{"   " x (length($1)/2)}e' YOUR_FILE

Из vim при редактировании YOUR_FILE:

:%!perl -pe 's{^((?:  )+)}{"   " x (length($1)/2)}e'

Регулярное выражение соответствует началу строки, за которым следует (захваченный набор) один илибольше "двух космических" групп.Шаблон подстановки является выражением perl (отсюда и модификатор 'e'), который подсчитывает количество захваченных «двух пробельных» групп и создает строку с таким же количеством «трех пробельных» групп.Если в оригинале присутствовал «лишний» пробел, он сохраняется после замены.Так что, если у вас было три пробела раньше, у вас будет четыре после, пять раньше превратится в семь после и т. Д.

...