2011-10-07 4 views
5

Я занимаюсь головоломкой, где каждый английский символ заменяется на 2 символа. Например, «яблоко» будет записано как «crrng» a + 2 = c, ... и аналогично для pple. В python maketrans я смог это сделать.VIM Поиск и замена

Мне было интересно, если подобное возможно в VIM-поиске & заменить ??

Любые идеи ???

ответ

9

Если алфавитные символы расположены последовательно в целевой кодировке , используйте следующую команду подстановки .

:%s/./\=nr2char(char2nr(submatch(0))+2)/g 

Однако эта замена реализует некруглую смену букв. Круговой сдвиг может быть осуществлен двумя заменами, которые обрабатываются в нижнем регистре и прописными буквами.

:%s/\l/\=nr2char(char2nr('a') + (char2nr(submatch(0)) - char2nr('a') + 2) % 26)/g 
:%s/\u/\=nr2char(char2nr('A') + (char2nr(submatch(0)) - char2nr('A') + 2) % 26)/g 

Другой способ заключается в преобразовании символов с помощью функции tr(). Предположим, что переменная a содержит строчные буквы алфавита , расположенных в правильном порядке, а переменная a1 содержит строку символов , соответствующую значениям в a (ниже приведен пример для английских букв).

:let a = 'abcdefghijklmnopqrstuvwxyz' 
:let a1 = a[2:] . a[:1] 

Чтобы не вводить весь алфавит вручную, значение a может быть произведено следующим образом,

:let a = join(map(range(char2nr('a'), char2nr('z')), 'nr2char(v:val)'), '') 

Затем, чтобы заменить каждую букву в строке письма две позиции вниз алфавит, использовать замену

:%s/.*/\=tr(submatch(0), a . toupper(a), a1 . toupper(a1)) 

Это верно для ASCII и некоторых алфавитов в UTF-8, например. Английский.

Перед выполнением команды, убедитесь, что encoding вариант устанавливается соответствующим образом.

+0

Спасибо .. Но если я хочу, чтобы круглая замена ..как y-> a z-> b, возможно ли это в одной отдельной строке? – hari

+0

@hari: см. Редактирование ответа. –

+0

просто небольшое примечание: строка '.', которая объединяет строку, затрудняет чтение при кодировании на C++, я бы предпочел, чтобы она дополнялась пробелами с обеих сторон (кажется, что вы не играли в гольф в это время, учитывая пробелы после запятых !) – Benoit

0

Невозможно придумать что-либо в vim, но вы можете использовать утилиту командной строки unix 'tr' (означает перевод, я считаю).

1

Да, \= будет выполнять функцию

%s/\(.\)/\=nr2char(char2nr(submatch(1)) + 2)/g 
+1

Не нужно использовать подходящую группу, см. Решение ib. 'submatch (0)' будет соответствовать всему шаблону. – Benoit

0

Загадки вы охарактеризовали широко известна как цезарь шифр, и, как правило, осуществляется через tr команды или sed -e y/. Поскольку y недоступен в vim, вам понадобится довольно грязный взломать, как и ib, но вызов tr - гораздо приятнее.

Особенно учитывая угловой регистр y и z: Я предполагаю, что они должны быть сопоставлены с a и b соответственно?

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