【问题标题】:vim: escaping strings for substitution (vimscript)vim:转义字符串以进行替换(vimscript)
【发布时间】:2017-09-15 08:20:15
【问题描述】:

我目前写了一个在vim中编程时经常需要的替代函数。

我已经编写的函数看起来像这样,并且基本上可以运行用于搜索和替换内部没有任何特殊字符的字符串。我已经意识到要自动转义“/”。我的问题是,我必须如何调整该行中的 escape() 函数

execute ':silent :argdo %s/' . escape(searchPattern, '/') . '/' . escape(replacePattern, '/') . '/ge'

这样所有必须转义的字符都会自动转义?

" MAIN FUNCTION
" inspired by http://vimcasts.org/episodes/project-wide-find-and-replace/
function! SubstituteProjectwide(searchInput)
  :set hidden
  let cwd = getcwd()
  let filename=expand('%:p')
  call inputsave()
  let searchPattern = input('Search for: ', a:searchInput)
  let replacePattern = input('Replace "' . searchPattern . '" with: ')
  let filePattern = input('Filepattern: ', cwd . '/**/*.*')
  call inputrestore()
  execute ':silent :args ' . filePattern
  execute ':silent :vimgrep /' . searchPattern . '/g ##'
  execute ':silent :Qargs'
  execute ':silent :argdo %s/' . escape(searchPattern, '/\') . '/' . escape(replacePattern, '/\') . '/ge'
  execute ':silent :edit ' . filename
  echo 'Replaced "' . searchPattern . '" with "' . replacePattern . '" in ' . filePattern
endfunction

" VISUAL ENTRYPOINT WITH SELECTED TEXT
function! SubstituteProjectwideVisual()
  let v = @*
  call SubstituteProjectwide(GetVisualSelectedText())
endfunction
:vnoremap <F6> :call SubstituteProjectwideVisual()<cr>

" NORMAL ENTRYPOINT WIHT WORD UNDER CURSOR
function! SubstituteProjectwideNormal()
  let wordUnderCursor = expand("<cword>")
  call SubsituteProjectwide(wordUnderCursor)
endfunction
:nnoremap <F6> :call SubstituteProjectwideNormal()<cr>

" GETTING THE FILES WICH CONTAIN SEARCH PATTERN
" copied from http://vimcasts.org/episodes/project-wide-find-and-replace/
command! -nargs=0 -bar Qargs execute 'args' QuickfixFilenames()
function! QuickfixFilenames()
  let buffer_numbers = {}
  for quickfix_item in getqflist()
    let buffer_numbers[quickfix_item['bufnr']] = bufname(quickfix_item['bufnr'])
  endfor
  return join(map(values(buffer_numbers), 'fnameescape(v:val)'))
endfunction

" GETTING THE CURRENT VISUAL SELECTION
" copied from: https://stackoverflow.com/questions/1533565/how-to-get-visually-selected-text-in-vimscript
function! GetVisualSelectedText()
  let [line_start, column_start] = getpos("'<")[1:2]
  let [line_end, column_end] = getpos("'>")[1:2]
  let lines = getline(line_start, line_end)
  if len(lines) == 0
    return ''
  endif
  let lines[-1] = lines[-1][: column_end - (&selection == 'inclusive' ? 1 : 2)]
  let lines[0] = lines[0][column_start - 1:]
  return join(lines, "\n")
endfunction

更新

我设法逃脱了许多这样的角色

escape(searchPattern, ' / \') . '/' . escape(replacePattern, ' / \')

但是我怎么知道我必须转义哪些字符列表,当基本上有可能时,每个字符都可以在搜索中以及替换字符串中?

【问题讨论】:

    标签: vim escaping substitution


    【解决方案1】:

    要进行文字替换,请指定 "very-nomagic" (:help /\V) 并转义分隔符 (/) 和 \ 在源代码中。

    在替换中,如果设置了 'magic' 选项,&amp;~ 也必须转义。 (\V 在这里不起作用。)

    execute ':silent :argdo %s/\V' . escape(searchPattern, '/\') . '/' . escape(replacePattern, '/\' . (&magic ? '&~' : '')) . '/ge'
    

    必须将换行符(如果可能)从 ^M 更改为 \n

    execute ':silent :argdo %s/\V' . substitute(escape(searchPattern, '/\'),"\n",'\\n','ge') . '/' . escape(replacePattern, '/\' . (&magic ? '&~' : '')) . '/ge'
    

    【讨论】:

    • 它似乎在运行。我必须用一些更复杂的搜索词来测试它
    • @divramod 请记住,您还需要转义&amp;~,至少在替换模式中是这样。请参阅@ingo-karkat 答案中最后一行的结尾。
    【解决方案2】:

    这并不能完全回答您的问题,而是另一种看待您要解决的问题的方式。我不完全遵循 :args 设置为您做的事情,因为 quickfix 在 :vimgrep 之后包含您需要的所有信息。

    我的 vimrc 中有这个:

    nnoremap <F3> :vimgrep // $PROJECT_ROOT_DIR/src/**/*.{cpp,h,c,inl,msg}<C-Left><C-Left><Right>
    

    显然你会想要自定义搜索路径,因为它只关注我每次启动 Vim 时配置的特定文件层次结构中的上述五个文件扩展名...

    无论如何,一旦你知道了,:cr 确保你在开始,然后在宏中执行你想要的搜索和替换。如果您愿意,您实际上可以在前几个发现中对其进行测试,但随后...

    qbq清除'b'寄存器。

    qa开始录制'a'宏'

    :%s/this/that/g 启动宏并将“that”替换为“this”。 (按回车)

    :w|cnf写入文件并进入下一个(回车)

    q停止录制“a”宏。

    然后qb@a@bq 将运行一次宏,将其保存在@b 中。然后运行 (type) @b 再一次,它会一直调用自己,直到完成。

    【讨论】:

      猜你喜欢
      • 2011-04-28
      • 1970-01-01
      • 2012-02-17
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-09-19
      • 1970-01-01
      相关资源
      最近更新 更多