前言
我知道有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]))
答案 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
如您所见,您现在有一个包含所有搜索结果的列表。
在上面的链接中,您可以找到一个通用的解决方案,它将函数作为参数。