如何从缓冲区中获取至少2个以某些字符开头的字符?

时间:2017-12-29 13:24:19

标签: vim

前言

我知道有match()matchstr()等等,但似乎没有函数返回字符串中的所有匹配项(不是子匹配项)。可以处理matchstrpos(),但每次都有很大的开销解析正则表达式。这就是我将split()函数用于与性能相关的任务的原因。

目标

我需要在缓冲区中找到至少2个以“text”开头的字符的所有单词。模式很简单。例如,要查找以“f”开头的所有单词,我使用f\w\+但我不知道如何反转模式以传递到split()函数。现在我使用\W,然后使用filter()函数过滤单词。我认为算法可能会更快。

当前代码

function! completion#filter(base, lastIndex, i, word)
    return a:word[1] != "" && a:word[0:a:lastIndex] ==# a:base

    " also tried this
    " return a:word[1] != "" && strridx(a:word, a:base, 0) == 0
endfunction

let words = split(join(getline(1, "$"), "\n"), '\W\+')
call filter(words, funcref("completion#filter", [a:base, len(a:base) - 1]))

1 个答案:

答案 0 :(得分:1)

以下解决方案取自此处: https://vi.stackexchange.com/questions/4305/is-it-possible-to-get-the-matched-string-after-calling-search

请考虑在那里留下一个upvote!

基本技巧是:s\=:h :s\=)与:s//n:h :s)相结合。

:s\=允许我们在:s//命令中评估vimscript,而n标志允许我们跳过一个实际的替代。

因此,在最简单的形式中,它可以像这样使用:

let b = [] | execute ':keeppatterns %s/f\w\+/\=add(b, submatch(0))/gn' | echo b

如您所见,您现在有一个包含所有搜索结果的列表。

在上面的链接中,您可以找到一个通用的解决方案,它将函数作为参数。