Увеличение и уменьшение числа

У меня есть этот текст с цифрами:

My numbers are 04, and 0005
My numbers are 05, and 0006
My numbers are 06, and 0035
My numbers are 07, and 0007
My numbers are 08, and 0009

Это код, который я всегда использовал для увеличения или уменьшения чисел в выделении / выделении блока / столбце: p.e. увеличить последние 4 числа в тексте выше на 8:

 '<,'>s/\%V\<\d\{4}\>/\=submatch(0)+8/g

но сегодня я заметил, что он делает странные вещи. Это результат:

My numbers are 04, and 13
My numbers are 05, and 14
My numbers are 06, and 37 <---
My numbers are 07, and 15
My numbers are 08, and 17
  • он удаляет ведущие нули (я хотел бы сохранить их, если есть ведущие нули, и не добавлять их, если нет ведущих нулей)
  • он добавил 8 ко всем числам, кроме 37, где он добавил 2. (почему?)

Может ли кто-нибудь помочь мне найти регулярное выражение для добавления / вычитания чисел из выделения (или выделения блока) без потери начальных нулей?

примечание:
Я заметил, что Control A + Control x сохраняет начальные нули и выполняет работу так, как я хочу, но:
- Я видел, что его нельзя использовать в замещающей команде ('‹,'> s /)
- и я не знаю, как добавить pe 200 в список номеров (200 х?)


person Reman    schedule 17.04.2012    source источник
comment
Если это поможет, я предпочитаю делать такие вещи, это писать внешний фильтр (например, на perl), а затем использовать! /Path/filter.pl в блоке. Это упрощает решение проблем, а фильтры легко повторно использовать и изменять.   -  person CodeClown42    schedule 17.04.2012


Ответы (3)


ведущий ноль составляет число 8-based.

(0035)8 == (29)10

Вы можете протестировать в vim:

:echo 0035 == 29

Он напечатает 1 (true).


Попробуй это:

:%s/\(\<[0-9]\{4}\>\)\@=0*\([0-9]*\)/\=submatch(2)+8/
person kev    schedule 17.04.2012
comment
@Kev, я проверил твое регулярное выражение. Он работает нормально, но я заметил, что он не учитывает числа, когда он прикреплен к текстовому символу p.e. text22text или 22text. Что мне нужно изменить, чтобы это работало? (кстати, я полагаю, что с помощью регулярного выражения submatch невозможно сохранить ведущие нули, не так ли?) - person Reman; 18.04.2012

это?

:%s/\v[0-9]{4}/\=printf("%04d", substitute(submatch(0), '^0\+', '', 0)+8)/   

ИЗМЕНИТЬ

@Remonn, вы должны указать правильный образец ввода в своем вопросе. строка выше работает на вашем примере.

для вашего нового требования взгляните на строку ниже:

Вход:

40
20
120
0500
230
0000000020
00000000000005000

vim cmd:

:%!awk '{if($0~/^0/){f="\%"length($0)"d";$0+=8; s=sprintf(f,$0); gsub(/ /,"0",s);}else s=$0+8;print s}'

изменит файл на:

48
28
128
0508
238
0000000028
00000000000005008

в моем cmd я использовал '%', вы можете выбрать (v) числа, с которыми хотите проделать трюки, а затем попробовать с моим cmd.

удачи

person Kent    schedule 17.04.2012
comment
Спасибо, Кент, хорошее регулярное выражение. Однако я заметил, что это также применяется для цифр без начальных нулей и начальных нулей. Я хотел бы сохранить ведущие нули, если они есть, и не добавлять их, если их нет (как это делают C-A / C-X). - person Reman; 17.04.2012
comment
возьмите эти числа: 40, 20, 120, 0500, 230 - регулярное выражение выше дает неправильные результаты. Выход: 48, 28, 200, 1300, 310 - person Reman; 18.04.2012
comment
@Kent Я говорил об общем регулярном выражении в своем вопросе :) Спасибо за awk. Работает нормально. Я сохраню это. Однако awk не изменяет числа @ / в тексте, как это делает регулярное выражение kev. (Кстати, вы, ребята, добавляете @Name перед комментарием?) - person Reman; 18.04.2012

По умолчанию Vim обрабатывает числа, начинающиеся с 0, как восьмеричные.

По этой причине у меня есть это в моем .vimrc:

set   nrformats-=octal  " Don't bother with octal, I never use it
person Johnsyweb    schedule 18.04.2012
comment
Привет, Johnsyweb, я проверил это, но ничего не изменилось. - person Reman; 18.04.2012