2017-12-29 7 views
1

はじめはいくつかの文字で始まる2文字以上のバッファ内のすべての単語を取得する方法は?

私はmatch()matchstr()などがある知っているが、それは、文字列(いないサブ試合)ですべての一致を返す機能がないようです。 matchstrpos()を扱うことは可能ですが、たびに大きな正規表現解析正規表現があります。だから私は性能関連の仕事のためにsplit()関数を使うのです。

私は少なくとも2つの文字が「テキスト」で始まるバッファ内のすべての単語を見つける必要がある

目標。パターンはとてもシンプルです。たとえば、 "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

まあ、コードはここにあります。 – Evgeniy

+1

最後にすべての単語のリストが必要ですか? –

答えて

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 

、あなたは今、すべて、検索結果のリストを持っています。

上記のリンクでは、関数を引数として取る一般的な解を見つけることができます。

+0

パーフェクト。このコードは2倍〜2.5倍速く動作します。 – Evgeniy

+0

しかし、非常に奇妙な問題があります。 'add'関数を呼び出すと、検索に膨大なオーバーヘッドが発生します。私の '.vimrc'では現在800行あり、一致するものがなければ1msの時間がかかります。しかし、わずか700のマッチがあるとき、コマンドは面倒な** 100ms **を要する。 – Evgeniy

+0

@Evgeniyあなたは、 'split'の前に':g // p'で回答を改善しようとすることができます。しかし、それが速いのかどうか分からない –

関連する問題