2009-10-11 17 views
31

En vim, a menudo quiero buscar en una cadena con caracteres complejos que necesitan escaparse. ¿Hay alguna manera de desactivar el significado de todos los caracteres especiales, como el modo regex-off en menos, o fgrep?¿Concordancia de cadena exacta en vim? (Al igual que el modo 'regex-off' en menos.)

Estoy lidiando con cuerdas particularmente peludas; he aquí un ejemplo:

((N/N)/(N/N))/N 

No tener que escapar de ningún personaje para hacer una búsqueda en vim sería un ahorro de tiempo importante.

\ V en Vim ayuda con algunos metacaracteres, pero críticamente no/o \.


¡Gracias a todos! Al final, he añadido esto a mi .vimrc:

command! -nargs=1 S let @/ = escape('<args>', '\') 
nmap <Leader>S :execute(":S " . input('Regex-off: /'))<CR> 
+1

En 'less', puede desactivar la expresión regular con'/'' Ctrl-R'. – blubb

Respuesta

18

En cuanto a su ejemplo específico, probablemente la forma más sencilla de hacerlo (ya que \ V no ayudará aquí) es el uso de ? en lugar de /: entonces no tendrá que escapar los / s:

?((N/N)/(N/N))/N 

Esto buscará hacia atrás en lugar de hacia delante, pero siempre puede hacer 'N' en lugar de 'n' para buscar hacia adelante después de la primera vez.O puede presionar / seguido de la tecla de cursor hacia arriba para escapar automáticamente de las barras diagonales.

Sin embargo, no hay nada que pueda hacer para evitar las barras diagonales inversas. Creo que se puede hacer:

:let @/ = escape(pattern, '\') 

y luego usar n a buscar, pero no es probablemente mucho más fácil. Lo mejor que puedo llegar a decir:

:command! -nargs=1 S let @/ = escape('<args>', '\') 

Después, realice:

:S (N)/(N+1)\(N) 
n 
+0

Excelentes respuestas, pero escapar de la entrada es probablemente lo más cerca que estaré de No-regex. Sin búsquedas mientras escribes, pero tampoco "menos". – jogloran

+0

: g # ((N/N)/(N/N))/N ##! funciona para tu ejemplo. Para la búsqueda como se escribe,? ((N/N)/(N/N))/N también funciona, pero busca hacia atrás. – Teajay

27

Dependiendo de la cadena exacta que está buscando, el prefijo \V probablemente el truco.
Ver :help \V:

after: \v  \m  \M  \V   matches ~ 
       'magic' 'nomagic'  
      $  $  $  \$   matches end-of-line 
      .  .  \.  \.   matches any character 
      *  *  \*  \*   any number of the previous atom 
     ()  \(\)  \(\)  \(\)  grouping into an atom 
      |  \|  \|  \|   separating alternatives 
      \a  \a  \a  \a   alphabetic character 
      \\  \\  \\  \\   literal backslash 
      \.  \.  .  .   literal dot 
      \{  {  {  {   literal '{' 
      a  a  a  a   literal 'a' 

Así que si tengo una cadena hello.*$world, puedo usar el comando /\V.*$ para encontrar justo .*$ - la única parte de la cadena de de que fuera necesario escapando es otra barra invertida, pero todavía se puede agrupar, etc. escapando del símbolo especial.


Otro comando que puede utilizar para "evitar" barras diagonales es:

:g #\V((N/N)/(N/N))/N# 

El comando :g es una búsqueda global, señalando que:

:[range]g[lobal]/{pattern}/[cmd] 
         Execute the Ex command [cmd] (default ":p") on the 
         lines within [range] where {pattern} matches. 

Instead of the '/' which surrounds the {pattern}, you can use any other 
single byte character, but not an alphanumeric character, '\', '"' or '|'. 
This is useful if you want to include a '/' in the search pattern or 
replacement string. 

Entonces, ¿dónde he usado un # , puede usar ?, @ o cualquier otro carácter que cumpla la condición anterior. El truco con el comando :g es que espera un comando al final, por lo que si no tiene un espacio posterior después del carácter final, no realizará la búsqueda como era de esperar. Y nuevamente, aunque esté usando \V, igual tendrá que escapar de las barras diagonales inversas.

Si eso todavía no corta por usted, this Nabble post tiene una sugerencia que toma una cadena literal con barras invertidas incrustados y otros caracteres especiales Vim, y afirma que buscarlo sin ningún problema; pero requiere crear una función Vim, que puede o no estar bien en su entorno.

+0

Gracias Mark! Pero estoy tratando de hacer coincidir cadenas que probablemente estén construidas para frustrar el escape de vim. He editado la pregunta con un ejemplo. ¿Conoce alguna forma de deshacerse del significado de _todos los metacaracteres especiales, incluidos \ y /, como/usr/bin/less con no-regex (Ctrl + R)? – jogloran

5

Tal vez algo como esto:

nmap <Leader>s :execute '/\V' . escape(input('/'), '\\/')<CR> 

él se puede dar un aviso / y se comportan de otra forma como la búsqueda incorporada, pero no hará búsquedas como lo hace u otro tipo de cosas.

+0

(Esto utiliza ': /', que funciona en línea, por lo que coloca el cursor al principio de la línea del partido; (en oposición a '/', que salta a la posición del partido dentro de su línea)) –

+0

el segundo '' \ '' en 'escape (..., '\\ /')' es redundante, porque el 'segundo parámetro de escape()' es una lista de caracteres, y las comillas simples denotan un [''...' 'literal string] (http://vimdoc.sourceforge.net/htmldoc/eval.html#literal-string) donde no se interpretan secuencias de escape. (Sugiero escribir ''/ \'' para que sea visualmente evidente que '' '' 'no escapa del'/'.) –

Cuestiones relacionadas