2011-10-07 21 views
5

Estaba haciendo algunos acertijos, donde cada char inglés es reemplazado por 2 char advanced. Por ejemplo, "apple" se escribiría como "crrng" a + 2 = c, ... y de manera similar para pple. En python maketrans pude hacerlo.Búsqueda y reemplazo de VIM

Me preguntaba si algo similar es posible en la búsqueda de VIM & reemplazar ??

¿Alguna idea ???

Respuesta

9

Si los caracteres alfabéticos se disponen secuencialmente en objetivo codificación , utilizar el comando siguiente sustitución .

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

Sin embargo, este reemplazo implementa un cambio de letra no circular. Se puede implementar un cambio circular mediante dos sustituciones que manejen por separado las letras minúsculas y letras mayúsculas.

:%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 

Otra forma es traducir los caracteres mediante la función tr(). Vamos a suponemos que la variable a contiene caracteres en minúsculas de un alfabeto dispuestas en el orden correcto, y la variable a1 contener la cadena de caracteres correspondientes a los de a (a continuación es un ejemplo de las letras inglesas).

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

Para evitar tener que escribir el alfabeto completo con la mano, el valor de a se pueden producir de la siguiente manera,

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

Entonces, para reemplazar cada letra en una línea de una carta dos posiciones abajo de la alfabeto, utilizar la sustitución

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

Es cierto para ASCII y algunos alfabetos en UTF-8, p. Ej. Inglés.

Antes de ejecutar el comando, asegúrese de que la opción encoding se ajusta en consecuencia.

+0

Gracias .. Pero si quiero tener un reemplazo circular ...como y-> a z-> b ¿es posible en una sola línea? – hari

+0

@hari: ver la edición de la respuesta. –

+0

solo un pequeño comentario: el '.' que concatena cadena hace que sea difícil de leer cuando codificas en C++, yo preferiría que estuviera relleno con espacios en ambos lados (parece que no lo jugaste esta vez, dados los espacios después de las comas !) – Benoit

0

No se puede pensar en nada en vim, pero podría usar la utilidad de línea de comandos de unix 'tr' (que significa translate, creo).

1

Sí, \= ejecutará la función

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

no es necesario utilizar un grupo coincidente, consulte la solución de ib. 'submatch (0)' coincidirá con el patrón completo. – Benoit

0

El rompecabezas que describes es ampliamente conocido como el cifrado César, y normalmente se implementa mediante el comando tr o sed -e y/. Como y no está disponible en vim, necesitarás un truco bastante sucio como ib propuesto, pero llamar a tr es un trabajo mucho más agradable.

Especialmente teniendo en cuenta el caso de la esquina de y y z: supongo que estos deberían asignarse a ayb, respectivamente?

Cuestiones relacionadas