2011-10-07 165 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'(代表translate,我相信)。

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?