Подтвердить что ты не робот

Использование замены на переменную

Как я могу выполнить следующую функцию в vimscript?

fun! Foo()
    let l:bar = "Hello there, world!"
    # Perform a substitution on l:bar, changing "world" to "kitten"
endfun

То есть, как выполнить подстановку для переменной, а не текущего буфера.

Я знаю, что для замены в буфере я могу написать

silent :%s/world/kitten/g

но какова эквивалентная команда для замены на переменную?

4b9b3361

Ответ 1

См. :help substitute of :help substitute().

Это аналог команды подстановки (см. :help :substitute).

substitute({expr}, {pat}, {sub}, {flags})       *substitute()*

    The result is a String, which is a copy of {expr}, in which
    the first match of {pat} is replaced with {sub}.  This works
    like the ":substitute" command (without any flags).  But the
    matching with {pat} is always done like the 'magic' option is
    set and 'cpoptions' is empty (to make scripts portable).
    'ignorecase' is still relevant.  'smartcase' is not used.
    See |string-match| for how {pat} is used.
    And a "~" in {sub} is not replaced with the previous {sub}.
    Note that some codes in {sub} have a special meaning
    |sub-replace-special|.  For example, to replace something with
    "\n" (two characters), use "\\\\n" or '\\n'.
    When {pat} does not match in {expr}, {expr} is returned
    unmodified.
    When {flags} is "g", all matches of {pat} in {expr} are
    replaced.  Otherwise {flags} should be "".
    Example: >
        :let &path = substitute(&path, ",\\=[^,]*$", "", "")
    This removes the last component of the 'path' option. 
        :echo substitute("testing", ".*", "\\U\\0", "")
    results in "TESTING".

В вашем примере я предполагаю, что let l:bar = substitute(l:bar, "world", "kitten", "") должен работать

Ответ 2

Мне надоело искать руководство vim, чтобы избежать магии при создании моего плагина vim-encode, здесь чистая реализация vimscript для простого поиск и замена текста

Использование: s:strreplace("abc","a","b") возвращает "bbc", s:strreplace("abc",["a","b"],["b","a"]) возвращает "bac"

    func! s:strfind(s,find,start)
            if type(a:find)==1
                    let l:i = a:start
                    while l:i<len(a:s)
                            if strpart(a:s,l:i,len(a:find))==a:find
                                    return l:i
                            endif
                            let l:i+=1
                    endwhile
                    return -1
            elseif type(a:find)==3
                    " a:find is a list
                    let l:i = a:start
                    while l:i<len(a:s)
                            let l:j=0
                            while l:j<len(a:find)
                                    if strpart(a:s,l:i,len(a:find[l:j]))==a:find[l:j]
                                            return [l:i,l:j]
                                    endif
                                    let l:j+=1
                            endwhile
                            let l:i+=1
                    endwhile
                    return [-1,-1]
            endif
    endfunc

    func! s:strreplace(s,find,replace)
            if len(a:find)==0
                    return a:s
            endif
            if type(a:find)==1 && type(a:replace)==1
                    let l:ret = a:s
                    let l:i = s:strfind(l:ret,a:find,0)
                    while l:i!=-1
                            let l:ret = strpart(l:ret,0,l:i).a:replace.strpart(l:ret,l:i+len(a:find))
                            let l:i = s:strfind(l:ret,a:find,l:i+len(a:replace))
                    endwhile
                    return l:ret
            elseif  type(a:find)==3 && type(a:replace)==3 && len(a:find)==len(a:replace)
                    let l:ret = a:s
                    let [l:i,l:j] = s:strfind(l:ret,a:find,0)
                    while l:i!=-1
                            let l:ret = strpart(l:ret,0,l:i).a:replace[l:j].strpart(l:ret,l:i+len(a:find[l:j]))
                            let [l:i,l:j] = s:strfind(l:ret,a:find,l:i+len(a:replace[l:j]))
                    endwhile
                    return l:ret
            endif

    endfunc